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$
2666830Sobrien#
27252015ShrsIFCONFIG_CMD="/sbin/ifconfig"
2825184Sjkh
29252015Shrs# Maximum number of addresses expanded from a address range specification.
30252015Shrs_IPEXPANDMAX=31
31252015Shrs
32113674Smtm#
33113674Smtm# Subroutines commonly used from network startup scripts.
34113674Smtm# Requires that rc.conf be loaded first.
35113674Smtm#
3625184Sjkh
37178356Ssam# ifn_start ifn
38197147Shrs#	Bring up and configure an interface.  If some configuration is
39225560Sbrueffer#	applied, print the interface configuration.
40178356Ssam#
41178356Ssamifn_start()
42178356Ssam{
43178356Ssam	local ifn cfg
44178356Ssam	ifn="$1"
45178356Ssam	cfg=1
46178356Ssam
47178356Ssam	[ -z "$ifn" ] && err 1 "ifn_start called without an interface"
48178356Ssam
49178356Ssam	ifscript_up ${ifn} && cfg=0
50178356Ssam	ifconfig_up ${ifn} && cfg=0
51256040Shrs	if ! noafif $ifn; then
52256040Shrs		afexists inet && ipv4_up ${ifn} && cfg=0
53256040Shrs		afexists inet6 && ipv6_up ${ifn} && cfg=0
54256040Shrs		afexists ipx && ipx_up ${ifn} && cfg=0
55256040Shrs	fi
56197139Shrs	childif_create ${ifn} && cfg=0
57178356Ssam
58178356Ssam	return $cfg
59178356Ssam}
60178356Ssam
61197139Shrs# ifn_stop ifn
62225560Sbrueffer#	Shutdown and de-configure an interface.  If action is taken,
63197147Shrs#	print the interface name.
64178356Ssam#
65178356Ssamifn_stop()
66178356Ssam{
67178356Ssam	local ifn cfg
68178356Ssam	ifn="$1"
69178356Ssam	cfg=1
70178356Ssam
71197139Shrs	[ -z "$ifn" ] && err 1 "ifn_stop called without an interface"
72178356Ssam
73256040Shrs	if ! noafif $ifn; then
74256040Shrs		afexists ipx && ipx_down ${ifn} && cfg=0
75256040Shrs		afexists inet6 && ipv6_down ${ifn} && cfg=0
76256040Shrs		afexists inet && ipv4_down ${ifn} && cfg=0
77256040Shrs	fi
78178356Ssam	ifconfig_down ${ifn} && cfg=0
79178356Ssam	ifscript_down ${ifn} && cfg=0
80197139Shrs	childif_destroy ${ifn} && cfg=0
81178356Ssam
82178356Ssam	return $cfg
83178356Ssam}
84178356Ssam
85256255Shrs# ifn_vnetup ifn
86256255Shrs#	Move ifn to the specified vnet jail.
87256255Shrs#
88256255Shrsifn_vnetup()
89256255Shrs{
90256255Shrs
91256255Shrs	ifn_vnet0 $1 vnet
92256255Shrs}
93256255Shrs
94256255Shrs# ifn_vnetdown ifn
95256255Shrs#	Reclaim ifn from the specified vnet jail.
96256255Shrs#
97256255Shrsifn_vnetdown()
98256255Shrs{
99256255Shrs
100256255Shrs	ifn_vnet0 $1 -vnet
101256255Shrs}
102256255Shrs
103256255Shrs# ifn_vnet0 ifn action
104256255Shrs#	Helper function for ifn_vnetup and ifn_vnetdown.
105256255Shrs#
106256255Shrsifn_vnet0()
107256255Shrs{
108256255Shrs	local _ifn _cfg _action _vnet
109256255Shrs	_ifn="$1"
110256255Shrs	_action="$2"
111256255Shrs	_cfg=1
112256255Shrs
113256255Shrs	if _vnet=$(vnetif $_ifn); then
114256255Shrs		${IFCONFIG_CMD} $_ifn $_action $_vnet && _cfg=0
115256255Shrs	fi
116256255Shrs
117256255Shrs	return $_cfg
118256255Shrs}
119256255Shrs
120113674Smtm# ifconfig_up if
121113674Smtm#	Evaluate ifconfig(8) arguments for interface $if and
122113674Smtm#	run ifconfig(8) with those arguments. It returns 0 if
123113674Smtm#	arguments were found and executed or 1 if the interface
124147088Sbrooks#	had no arguments.  Pseudo arguments DHCP and WPA are handled
125147088Sbrooks#	here.
126113674Smtm#
127113674Smtmifconfig_up()
128113674Smtm{
129197139Shrs	local _cfg _ipv6_opts ifconfig_args
130147088Sbrooks	_cfg=1
131147088Sbrooks
132222515Sbz	# Make sure lo0 always comes up.
133222515Sbz	if [ "$1" = "lo0" ]; then
134222515Sbz		_cfg=0
135222515Sbz	fi
136222515Sbz
137197139Shrs	# ifconfig_IF
138147088Sbrooks	ifconfig_args=`ifconfig_getargs $1`
139113674Smtm	if [ -n "${ifconfig_args}" ]; then
140252015Shrs		eval ${IFCONFIG_CMD} $1 ${ifconfig_args}
141147088Sbrooks		_cfg=0
142113674Smtm	fi
143147088Sbrooks
144197139Shrs	# inet6 specific
145256040Shrs	if ! noafif $1 && afexists inet6; then
146222733Shrs		if checkyesno ipv6_activate_all_interfaces; then
147222733Shrs			_ipv6_opts="-ifdisabled"
148222746Shrs		elif [ "$1" != "lo0" ]; then
149222733Shrs			_ipv6_opts="ifdisabled"
150212574Shrs		fi
151197139Shrs
152222733Shrs		# backward compatibility: $ipv6_enable
153222733Shrs		case $ipv6_enable in
154222733Shrs		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
155253520Shrs			case $1 in
156253520Shrs			bridge[0-9]*)
157253520Shrs				# No accept_rtadv by default on if_bridge(4)
158253520Shrs				# to avoid a conflict with the member
159253520Shrs				# interfaces.
160253520Shrs			;;
161253520Shrs			*)
162253520Shrs				if ! checkyesno ipv6_gateway_enable; then
163253520Shrs					_ipv6_opts="${_ipv6_opts} accept_rtadv"
164253520Shrs				fi
165253520Shrs			;;
166253520Shrs			esac
167230453Shrs		;;
168222733Shrs		esac
169222733Shrs
170225521Shrs		case $ipv6_cpe_wanif in
171225521Shrs		$1)
172225521Shrs			_ipv6_opts="${_ipv6_opts} -no_radr accept_rtadv"
173225521Shrs		;;
174225521Shrs		esac
175225521Shrs
176212574Shrs		if [ -n "${_ipv6_opts}" ]; then
177252015Shrs			${IFCONFIG_CMD} $1 inet6 ${_ipv6_opts}
178197526Shrs		fi
179212574Shrs
180212574Shrs		# ifconfig_IF_ipv6
181212574Shrs		ifconfig_args=`ifconfig_getargs $1 ipv6`
182212574Shrs		if [ -n "${ifconfig_args}" ]; then
183225522Shrs			# backward compatibility: inet6 keyword
184225522Shrs			case "${ifconfig_args}" in
185225522Shrs			:*|[0-9a-fA-F]*:*)
186225522Shrs				warn "\$ifconfig_$1_ipv6 needs " \
187225522Shrs				    "\"inet6\" keyword for an IPv6 address."
188225522Shrs				ifconfig_args="inet6 ${ifconfig_args}"
189225522Shrs			;;
190225522Shrs			esac
191252015Shrs			${IFCONFIG_CMD} $1 inet6 -ifdisabled
192252015Shrs			eval ${IFCONFIG_CMD} $1 ${ifconfig_args}
193212574Shrs			_cfg=0
194212574Shrs		fi
195212574Shrs
196230453Shrs		# $ipv6_prefix_IF will be handled in
197230453Shrs		# ipv6_prefix_hostid_addr_common().
198230453Shrs		ifconfig_args=`get_if_var $1 ipv6_prefix_IF`
199230453Shrs		if [ -n "${ifconfig_args}" ]; then
200252015Shrs			${IFCONFIG_CMD} $1 inet6 -ifdisabled
201230453Shrs			_cfg=0
202230453Shrs		fi
203230453Shrs
204229783Suqs		# backward compatibility: $ipv6_ifconfig_IF
205212574Shrs		ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF`
206212574Shrs		if [ -n "${ifconfig_args}" ]; then
207212574Shrs			warn "\$ipv6_ifconfig_$1 is obsolete." \
208212574Shrs			    "  Use ifconfig_$1_ipv6 instead."
209252015Shrs			${IFCONFIG_CMD} $1 inet6 -ifdisabled
210252015Shrs			eval ${IFCONFIG_CMD} $1 inet6 ${ifconfig_args}
211212574Shrs			_cfg=0
212212574Shrs		fi
213197139Shrs	fi
214197139Shrs
215252426Shrs	ifalias $1 link alias
216252426Shrs	ifalias $1 ether alias
217252426Shrs
218197139Shrs	if [ ${_cfg} -eq 0 ]; then
219252015Shrs		${IFCONFIG_CMD} $1 up
220197139Shrs	fi
221197139Shrs
222147088Sbrooks	if wpaif $1; then
223147682Sbrooks		/etc/rc.d/wpa_supplicant start $1
224147088Sbrooks		_cfg=0		# XXX: not sure this should count
225252230Srpaulo	elif hostapif $1; then
226252230Srpaulo		/etc/rc.d/hostapd start $1
227252230Srpaulo		_cfg=0
228147088Sbrooks	fi
229147088Sbrooks
230147088Sbrooks	if dhcpif $1; then
231149726Sbrooks		if [ $_cfg -ne 0 ] ; then
232252015Shrs			${IFCONFIG_CMD} $1 up
233149726Sbrooks		fi
234157706Sbrooks		if syncdhcpif $1; then
235157706Sbrooks			/etc/rc.d/dhclient start $1
236157706Sbrooks		fi
237147088Sbrooks		_cfg=0
238147088Sbrooks	fi
239147088Sbrooks
240147121Sbrooks	return $_cfg
241113674Smtm}
24225184Sjkh
243116029Smtm# ifconfig_down if
244161386Sbrooks#	returns 1 if wpa_supplicant or dhclient was stopped or
245161386Sbrooks#	the interface exists.
246116029Smtm#
247116029Smtmifconfig_down()
248116029Smtm{
249197139Shrs	local _cfg
250147121Sbrooks	_cfg=1
251116029Smtm
252147088Sbrooks	if wpaif $1; then
253147682Sbrooks		/etc/rc.d/wpa_supplicant stop $1
254147121Sbrooks		_cfg=0
255252230Srpaulo	elif hostapif $1; then
256252230Srpaulo		/etc/rc.d/hostapd stop $1
257252230Srpaulo		_cfg=0
258147088Sbrooks	fi
259147088Sbrooks
260147088Sbrooks	if dhcpif $1; then
261147088Sbrooks		/etc/rc.d/dhclient stop $1
262147088Sbrooks		_cfg=0
263147088Sbrooks	fi
264147088Sbrooks
265161386Sbrooks	if ifexists $1; then
266252015Shrs		${IFCONFIG_CMD} $1 down
267161386Sbrooks		_cfg=0
268161386Sbrooks	fi
269157706Sbrooks
270147121Sbrooks	return $_cfg
271116029Smtm}
272116029Smtm
273157706Sbrooks# get_if_var if var [default]
274197147Shrs#	Return the value of the pseudo-hash corresponding to $if where
275197147Shrs#	$var is a string containg the sub-string "IF" which will be
276197147Shrs#	replaced with $if after the characters defined in _punct are
277197147Shrs#	replaced with '_'. If the variable is unset, replace it with
278197147Shrs#	$default if given.
279157706Sbrooksget_if_var()
280157706Sbrooks{
281212578Shrs	local _if _punct _punct_c _var _default prefix suffix
282197139Shrs
283157706Sbrooks	if [ $# -ne 2 -a $# -ne 3 ]; then
284157706Sbrooks		err 3 'USAGE: get_if_var name var [default]'
285157706Sbrooks	fi
286157706Sbrooks
287157706Sbrooks	_if=$1
288157706Sbrooks	_punct=". - / +"
289157736Sbrooks	for _punct_c in $_punct; do
290157706Sbrooks		_if=`ltr ${_if} ${_punct_c} '_'`
291157706Sbrooks	done
292157706Sbrooks	_var=$2
293157706Sbrooks	_default=$3
294157706Sbrooks
295157706Sbrooks	prefix=${_var%%IF*}
296157706Sbrooks	suffix=${_var##*IF}
297168033Sache	eval echo \${${prefix}${_if}${suffix}-${_default}}
298157706Sbrooks}
299157706Sbrooks
300197139Shrs# _ifconfig_getargs if [af]
301225560Sbrueffer#	Prints the arguments for the supplied interface to stdout.
302225560Sbrueffer#	Returns 1 if empty.  In general, ifconfig_getargs should be used
303147088Sbrooks#	outside this file.
304147088Sbrooks_ifconfig_getargs()
305147088Sbrooks{
306212574Shrs	local _ifn _af
307147088Sbrooks	_ifn=$1
308197139Shrs	_af=${2+_$2}
309197139Shrs
310147088Sbrooks	if [ -z "$_ifn" ]; then
311147088Sbrooks		return 1
312147088Sbrooks	fi
313147088Sbrooks
314212574Shrs	get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT"
315147088Sbrooks}
316147088Sbrooks
317197139Shrs# ifconfig_getargs if [af]
318147088Sbrooks#	Takes the result from _ifconfig_getargs and removes pseudo
319147088Sbrooks#	args such as DHCP and WPA.
320147088Sbrooksifconfig_getargs()
321147088Sbrooks{
322256255Shrs	local _tmpargs _arg _args _vnet
323197139Shrs	_tmpargs=`_ifconfig_getargs $1 $2`
324147088Sbrooks	if [ $? -eq 1 ]; then
325147088Sbrooks		return 1
326147088Sbrooks	fi
327147088Sbrooks	_args=
328256255Shrs	_vnet=0
329147088Sbrooks
330147088Sbrooks	for _arg in $_tmpargs; do
331256255Shrs		case $_arg:$_vnet in
332256255Shrs		[Dd][Hh][Cc][Pp]:0) ;;
333256255Shrs		[Nn][Oo][Aa][Uu][Tt][Oo]:0) ;;
334256255Shrs		[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;;
335256255Shrs		[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;;
336256255Shrs		[Ww][Pp][Aa]:0) ;;
337256255Shrs		[Hh][Oo][Ss][Tt][Aa][Pp]:0) ;;
338256255Shrs		vnet:0)	_vnet=1 ;;
339256255Shrs		*:1)	_vnet=0 ;;
340256255Shrs		*:0)
341147088Sbrooks			_args="$_args $_arg"
342256255Shrs		;;
343147088Sbrooks		esac
344147088Sbrooks	done
345147088Sbrooks
346147088Sbrooks	echo $_args
347147088Sbrooks}
348147088Sbrooks
349149401Sbrooks# autoif
350225560Sbrueffer#	Returns 0 if the interface should be automatically configured at
351149401Sbrooks#	boot time and 1 otherwise.
352149401Sbrooksautoif()
353149401Sbrooks{
354197139Shrs	local _tmpargs _arg
355149401Sbrooks	_tmpargs=`_ifconfig_getargs $1`
356197139Shrs
357149401Sbrooks	for _arg in $_tmpargs; do
358149401Sbrooks		case $_arg in
359149401Sbrooks		[Nn][Oo][Aa][Uu][Tt][Oo])
360149401Sbrooks			return 1
361149401Sbrooks			;;
362149401Sbrooks		esac
363149401Sbrooks	done
364197139Shrs
365149401Sbrooks	return 0
366149401Sbrooks}
367149401Sbrooks
368147088Sbrooks# dhcpif if
369147088Sbrooks#	Returns 0 if the interface is a DHCP interface and 1 otherwise.
370147088Sbrooksdhcpif()
371147088Sbrooks{
372197139Shrs	local _tmpargs _arg
373147088Sbrooks	_tmpargs=`_ifconfig_getargs $1`
374197139Shrs
375252360Sdelphij	case $1 in
376252360Sdelphij	lo[0-9]*|\
377252360Sdelphij	stf[0-9]*|\
378252360Sdelphij	faith[0-9]*|\
379252360Sdelphij	lp[0-9]*|\
380252360Sdelphij	sl[0-9]*)
381252360Sdelphij		return 1
382252360Sdelphij		;;
383252360Sdelphij	esac
384225849Sdelphij	if noafif $1; then
385225849Sdelphij		return 1
386225849Sdelphij	fi
387225849Sdelphij
388147088Sbrooks	for _arg in $_tmpargs; do
389147088Sbrooks		case $_arg in
390147088Sbrooks		[Dd][Hh][Cc][Pp])
391147088Sbrooks			return 0
392147088Sbrooks			;;
393157706Sbrooks		[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
394157706Sbrooks			return 0
395157706Sbrooks			;;
396157706Sbrooks		[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
397157706Sbrooks			return 0
398157706Sbrooks			;;
399147088Sbrooks		esac
400147088Sbrooks	done
401197139Shrs
402147088Sbrooks	return 1
403147088Sbrooks}
404147088Sbrooks
405157706Sbrooks# syncdhcpif
406157706Sbrooks#	Returns 0 if the interface should be configured synchronously and
407157706Sbrooks#	1 otherwise.
408157706Sbrookssyncdhcpif()
409157706Sbrooks{
410197139Shrs	local _tmpargs _arg
411157706Sbrooks	_tmpargs=`_ifconfig_getargs $1`
412197139Shrs
413225849Sdelphij	if noafif $1; then
414225849Sdelphij		return 1
415225849Sdelphij	fi
416225849Sdelphij
417157706Sbrooks	for _arg in $_tmpargs; do
418157706Sbrooks		case $_arg in
419157706Sbrooks		[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
420157706Sbrooks			return 1
421157706Sbrooks			;;
422157706Sbrooks		[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
423157706Sbrooks			return 0
424157706Sbrooks			;;
425157706Sbrooks		esac
426157706Sbrooks	done
427197139Shrs
428197139Shrs	checkyesno synchronous_dhclient
429157706Sbrooks}
430157706Sbrooks
431147088Sbrooks# wpaif if
432147088Sbrooks#	Returns 0 if the interface is a WPA interface and 1 otherwise.
433147088Sbrookswpaif()
434147088Sbrooks{
435197139Shrs	local _tmpargs _arg
436147088Sbrooks	_tmpargs=`_ifconfig_getargs $1`
437197139Shrs
438147088Sbrooks	for _arg in $_tmpargs; do
439147088Sbrooks		case $_arg in
440147088Sbrooks		[Ww][Pp][Aa])
441147088Sbrooks			return 0
442147088Sbrooks			;;
443147088Sbrooks		esac
444147088Sbrooks	done
445197139Shrs
446147088Sbrooks	return 1
447147088Sbrooks}
448147088Sbrooks
449252230Srpaulo# hostapif if
450252230Srpaulo#	Returns 0 if the interface is a HOSTAP interface and 1 otherwise.
451252230Srpaulohostapif()
452252230Srpaulo{
453252230Srpaulo	local _tmpargs _arg
454252230Srpaulo	_tmpargs=`_ifconfig_getargs $1`
455252230Srpaulo
456252230Srpaulo	for _arg in $_tmpargs; do
457252230Srpaulo		case $_arg in
458252230Srpaulo		[Hh][Oo][Ss][Tt][Aa][Pp])
459252230Srpaulo			return 0
460252230Srpaulo			;;
461252230Srpaulo		esac
462252230Srpaulo	done
463252230Srpaulo
464252230Srpaulo	return 1
465252230Srpaulo}
466252230Srpaulo
467256255Shrs# vnetif if
468256255Shrs#	Returns 0 and echo jail if "vnet" keyword is specified on the
469256255Shrs#	interface, and 1 otherwise.
470256255Shrsvnetif()
471256255Shrs{
472256255Shrs	local _tmpargs _arg _vnet
473256255Shrs	_tmpargs=`_ifconfig_getargs $1`
474256255Shrs
475256255Shrs	_vnet=0
476256255Shrs	for _arg in $_tmpargs; do
477256255Shrs		case $_arg:$_vnet in
478256255Shrs		vnet:0)	_vnet=1 ;;
479256255Shrs		*:1)	echo $_arg; return 0 ;;
480256255Shrs		esac
481256255Shrs	done
482256255Shrs
483256255Shrs	return 1
484256255Shrs}
485256255Shrs
486197139Shrs# afexists af
487197139Shrs#	Returns 0 if the address family is enabled in the kernel
488197139Shrs#	1 otherwise.
489197139Shrsafexists()
490197139Shrs{
491197139Shrs	local _af
492197139Shrs	_af=$1
493197139Shrs
494197139Shrs	case ${_af} in
495222996Shrs	inet|inet6)
496222996Shrs		check_kern_features ${_af}
497197139Shrs		;;
498197697Shrs	ipx)
499197697Shrs		${SYSCTL_N} net.ipx > /dev/null 2>&1
500197697Shrs		;;
501197697Shrs	atm)
502197697Shrs		if [ -x /sbin/atmconfig ]; then
503197697Shrs			/sbin/atmconfig diag list > /dev/null 2>&1
504197697Shrs		else
505197697Shrs			return 1
506197697Shrs		fi
507197697Shrs		;;
508252426Shrs	link|ether)
509252426Shrs		return 0
510252426Shrs		;;
511197139Shrs	*)
512197139Shrs		err 1 "afexists(): Unsupported address family: $_af"
513197139Shrs		;;
514197139Shrs	esac
515197139Shrs}
516197139Shrs
517212574Shrs# noafif if
518212574Shrs#	Returns 0 if the interface has no af configuration and 1 otherwise.
519212574Shrsnoafif()
520212574Shrs{
521212574Shrs	local _if
522212574Shrs	_if=$1
523212574Shrs
524212574Shrs	case $_if in
525212574Shrs	pflog[0-9]*|\
526212574Shrs	pfsync[0-9]*|\
527256040Shrs	usbus[0-9]*|\
528212574Shrs	an[0-9]*|\
529212574Shrs	ath[0-9]*|\
530212574Shrs	ipw[0-9]*|\
531212577Shrs	ipfw[0-9]*|\
532212574Shrs	iwi[0-9]*|\
533212574Shrs	iwn[0-9]*|\
534212574Shrs	ral[0-9]*|\
535212574Shrs	wi[0-9]*|\
536212574Shrs	wl[0-9]*|\
537212574Shrs	wpi[0-9]*)
538212574Shrs		return 0
539212574Shrs		;;
540212574Shrs	esac
541212574Shrs
542212574Shrs	return 1
543212574Shrs}
544212574Shrs
545162490Sbrooks# ipv6if if
546162490Sbrooks#	Returns 0 if the interface should be configured for IPv6 and
547162490Sbrooks#	1 otherwise.
548162490Sbrooksipv6if()
549162490Sbrooks{
550212574Shrs	local _if _tmpargs i
551212574Shrs	_if=$1
552212574Shrs
553197139Shrs	if ! afexists inet6; then
554162490Sbrooks		return 1
555162490Sbrooks	fi
556197139Shrs
557197139Shrs	# lo0 is always IPv6-enabled
558212574Shrs	case $_if in
559197139Shrs	lo0)
560197139Shrs		return 0
561197139Shrs		;;
562197139Shrs	esac
563197139Shrs
564212574Shrs	case "${ipv6_network_interfaces}" in
565212575Shrs	$_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo])
566212575Shrs		# True if $ifconfig_IF_ipv6 is defined.
567212575Shrs		_tmpargs=`_ifconfig_getargs $_if ipv6`
568212575Shrs		if [ -n "${_tmpargs}" ]; then
569212575Shrs			return 0
570212575Shrs		fi
571197139Shrs
572230453Shrs		# True if $ipv6_prefix_IF is defined.
573230453Shrs		_tmpargs=`get_if_var $_if ipv6_prefix_IF`
574230453Shrs		if [ -n "${_tmpargs}" ]; then
575230453Shrs			return 0
576230453Shrs		fi
577230453Shrs
578212575Shrs		# backward compatibility: True if $ipv6_ifconfig_IF is defined.
579212575Shrs		_tmpargs=`get_if_var $_if ipv6_ifconfig_IF`
580212575Shrs		if [ -n "${_tmpargs}" ]; then
581212574Shrs			return 0
582212574Shrs		fi
583212575Shrs		;;
584212575Shrs	esac
585197139Shrs
586162490Sbrooks	return 1
587162490Sbrooks}
588162490Sbrooks
589197139Shrs# ipv6_autoconfif if
590197139Shrs#	Returns 0 if the interface should be configured for IPv6 with
591225560Sbrueffer#	Stateless Address Configuration; 1 otherwise.
592197139Shrsipv6_autoconfif()
593197139Shrs{
594197139Shrs	local _if _tmpargs _arg
595197139Shrs	_if=$1
596197139Shrs
597212577Shrs	case $_if in
598252360Sdelphij	lo[0-9]*|\
599212577Shrs	stf[0-9]*|\
600212577Shrs	faith[0-9]*|\
601212577Shrs	lp[0-9]*|\
602212577Shrs	sl[0-9]*)
603197139Shrs		return 1
604212577Shrs		;;
605212577Shrs	esac
606212574Shrs	if noafif $_if; then
607212574Shrs		return 1
608212574Shrs	fi
609212577Shrs	if ! ipv6if $_if; then
610212577Shrs		return 1
611212577Shrs	fi
612197139Shrs	if checkyesno ipv6_gateway_enable; then
613197139Shrs		return 1
614197139Shrs	fi
615197526Shrs	_tmpargs=`get_if_var $_if ipv6_prefix_IF`
616197526Shrs	if [ -n "${_tmpargs}" ]; then
617197526Shrs		return 1
618197526Shrs	fi
619212574Shrs	# backward compatibility: $ipv6_enable
620212574Shrs	case $ipv6_enable in
621212577Shrs	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
622242181Shrs		if checkyesno ipv6_gateway_enable; then
623242181Shrs			return 1
624253520Shrs		fi
625253520Shrs		case $1 in
626253520Shrs		bridge[0-9]*)
627253520Shrs			# No accept_rtadv by default on if_bridge(4)
628253520Shrs			# to avoid a conflict with the member
629253520Shrs			# interfaces.
630253520Shrs			return 1
631253520Shrs		;;
632253520Shrs		*)
633242181Shrs			return 0
634253520Shrs		;;
635253520Shrs		esac
636212577Shrs	;;
637197526Shrs	esac
638197526Shrs
639212574Shrs	_tmpargs=`_ifconfig_getargs $_if ipv6`
640212574Shrs	for _arg in $_tmpargs; do
641212574Shrs		case $_arg in
642212574Shrs		accept_rtadv)
643212574Shrs			return 0
644212574Shrs			;;
645212574Shrs		esac
646212574Shrs	done
647212574Shrs
648212574Shrs	# backward compatibility: $ipv6_ifconfig_IF
649212574Shrs	_tmpargs=`get_if_var $_if ipv6_ifconfig_IF`
650212574Shrs	for _arg in $_tmpargs; do
651212574Shrs		case $_arg in
652212574Shrs		accept_rtadv)
653212574Shrs			return 0
654212574Shrs			;;
655212574Shrs		esac
656212574Shrs	done
657212574Shrs
658197139Shrs	return 1
659197139Shrs}
660197139Shrs
661161386Sbrooks# ifexists if
662161386Sbrooks#	Returns 0 if the interface exists and 1 otherwise.
663161386Sbrooksifexists()
664161386Sbrooks{
665197139Shrs	[ -z "$1" ] && return 1
666252015Shrs	${IFCONFIG_CMD} -n $1 > /dev/null 2>&1
667161386Sbrooks}
668161386Sbrooks
669152441Sbrooks# ipv4_up if
670212578Shrs#	add IPv4 addresses to the interface $if
671152441Sbrooksipv4_up()
672152441Sbrooks{
673197139Shrs	local _if _ret
674152441Sbrooks	_if=$1
675197139Shrs	_ret=1
676197139Shrs
677222515Sbz	# Add 127.0.0.1/8 to lo0 unless otherwise specified.
678222515Sbz	if [ "${_if}" = "lo0" ]; then
679226649Shrs		ifconfig_args=`get_if_var ${_if} ifconfig_IF`
680222515Sbz		if [ -z "${ifconfig_args}" ]; then
681252015Shrs			${IFCONFIG_CMD} ${_if} inet 127.0.0.1/8 alias
682222515Sbz		fi
683222515Sbz	fi
684252015Shrs	ifalias ${_if} inet alias && _ret=0
685197139Shrs
686197139Shrs	return $_ret
687152441Sbrooks}
688152441Sbrooks
689197139Shrs# ipv6_up if
690197139Shrs#	add IPv6 addresses to the interface $if
691197139Shrsipv6_up()
692197139Shrs{
693197139Shrs	local _if _ret
694197139Shrs	_if=$1
695197139Shrs	_ret=1
696197139Shrs
697197139Shrs	if ! ipv6if $_if; then
698197139Shrs		return 0
699197139Shrs	fi
700197139Shrs
701252015Shrs	ifalias ${_if} inet6 alias && _ret=0
702226652Shrs	ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0
703197139Shrs	ipv6_accept_rtadv_up ${_if} && _ret=0
704197139Shrs
705197139Shrs	return $_ret
706197139Shrs}
707197139Shrs
708152441Sbrooks# ipv4_down if
709197147Shrs#	remove IPv4 addresses from the interface $if
710152441Sbrooksipv4_down()
711152441Sbrooks{
712197139Shrs	local _if _ifs _ret inetList oldifs _inet
713152441Sbrooks	_if=$1
714161386Sbrooks	_ifs="^"
715161386Sbrooks	_ret=1
716161386Sbrooks
717252015Shrs	ifalias ${_if} inet -alias && _ret=0
718161386Sbrooks
719255653Shrs	inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet ' | tr "\n\t" "$_ifs"`"
720252015Shrs
721161386Sbrooks	oldifs="$IFS"
722161386Sbrooks	IFS="$_ifs"
723161386Sbrooks	for _inet in $inetList ; do
724161386Sbrooks		# get rid of extraneous line
725253924Shrs		case $_inet in
726255653Shrs		inet\ *)	;;
727255653Shrs		*)		continue ;;
728253924Shrs		esac
729161386Sbrooks
730161386Sbrooks		_inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'`
731161386Sbrooks
732161386Sbrooks		IFS="$oldifs"
733252015Shrs		${IFCONFIG_CMD} ${_if} ${_inet} delete
734161386Sbrooks		IFS="$_ifs"
735161386Sbrooks		_ret=0
736161386Sbrooks	done
737161386Sbrooks	IFS="$oldifs"
738161386Sbrooks
739161386Sbrooks	return $_ret
740152441Sbrooks}
741152441Sbrooks
742197139Shrs# ipv6_down if
743197139Shrs#	remove IPv6 addresses from the interface $if
744197139Shrsipv6_down()
745197139Shrs{
746197139Shrs	local _if _ifs _ret inetList oldifs _inet6
747197139Shrs	_if=$1
748197139Shrs	_ifs="^"
749197139Shrs	_ret=1
750197139Shrs
751197139Shrs	if ! ipv6if $_if; then
752197139Shrs		return 0
753197139Shrs	fi
754197139Shrs
755197139Shrs	ipv6_accept_rtadv_down ${_if} && _ret=0
756226652Shrs	ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0
757252015Shrs	ifalias ${_if} inet6 -alias && _ret=0
758197139Shrs
759255653Shrs	inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet6 ' | tr "\n\t" "$_ifs"`"
760197139Shrs
761197139Shrs	oldifs="$IFS"
762197139Shrs	IFS="$_ifs"
763197139Shrs	for _inet6 in $inetList ; do
764197139Shrs		# get rid of extraneous line
765255653Shrs		case $_inet in
766255653Shrs		inet6\ *)	;;
767255653Shrs		*)		continue ;;
768255653Shrs		esac
769197139Shrs
770197139Shrs		_inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'`
771197139Shrs
772197139Shrs		IFS="$oldifs"
773252015Shrs		${IFCONFIG_CMD} ${_if} ${_inet6} -alias
774197139Shrs		IFS="$_ifs"
775197139Shrs		_ret=0
776197139Shrs	done
777197139Shrs	IFS="$oldifs"
778197139Shrs
779197139Shrs	return $_ret
780197139Shrs}
781197139Shrs
782252015Shrs# ifalias if af action
783252015Shrs#	Configure or remove aliases for network interface $if.
784113674Smtm#	It returns 0 if at least one alias was configured or
785252015Shrs#	removed, or 1 if there were none.
786113674Smtm#
787252015Shrsifalias()
788113674Smtm{
789197139Shrs	local _ret
790113674Smtm	_ret=1
791197139Shrs
792252015Shrs	afexists $2 || return $_ret
793252015Shrs
794197139Shrs	case "$2" in
795252426Shrs	inet|inet6|link|ether)
796252015Shrs		ifalias_af_common $1 $2 $3 && _ret=0
797197139Shrs		;;
798197139Shrs	esac
799197139Shrs
800197139Shrs	return $_ret
801197139Shrs}
802197139Shrs
803252015Shrs# ifalias_expand_addr af action addr
804252015Shrs#	Expand address range ("N-M") specification in addr.
805252015Shrs#	"addr" must not include an address-family keyword.
806252015Shrs#	The results will include an address-family keyword.
807197139Shrs#
808252015Shrsifalias_expand_addr()
809197139Shrs{
810253505Shrs	local _af _action
811197139Shrs
812253505Shrs	_af=$1
813253505Shrs	_action=$2
814253505Shrs	shift 2
815253505Shrs
816253505Shrs	afexists $_af || return
817253505Shrs	ifalias_expand_addr_$_af $_action $*
818197139Shrs}
819197139Shrs
820252015Shrs# ifalias_expand_addr_inet action addr
821252015Shrs#	Helper function for ifalias_expand_addr().  Handles IPv4.
822197139Shrs#
823252015Shrsifalias_expand_addr_inet()
824197139Shrs{
825253505Shrs	local _action _arg _cidr _cidr_addr _exargs
826252015Shrs	local _ipaddr _plen _range _iphead _iptail _iplow _iphigh _ipcount
827252015Shrs	local _retstr _c
828252015Shrs	_action=$1
829252015Shrs	_arg=$2
830253505Shrs	shift 2
831253505Shrs	_exargs=$*
832252015Shrs	_retstr=
833197139Shrs
834253505Shrs	case $_action:$_arg:$_exargs in
835253505Shrs	*:*--*)		return ;;	# invalid
836253505Shrs	tmp:*[0-9]-[0-9]*:*)		# to be expanded
837253505Shrs		_action="alias"
838253505Shrs	;;
839253505Shrs	*:*[0-9]-[0-9]*:*)		# to be expanded
840253505Shrs	;;
841253505Shrs	tmp:*:*netmask*)		# already expanded w/ netmask option
842253505Shrs		echo ${_arg%/[0-9]*} $_exargs && return
843253505Shrs	;;
844253505Shrs	tmp:*:*)			# already expanded w/o netmask option
845253505Shrs		echo $_arg $_exargs && return
846253505Shrs	;;
847253505Shrs	*:*:*netmask*)			# already expanded w/ netmask option
848253505Shrs		echo inet ${_arg%/[0-9]*} $_exargs && return
849253505Shrs	;;
850253505Shrs	*:*:*)				# already expanded w/o netmask option
851253505Shrs		echo inet $_arg $_exargs && return
852253505Shrs	;;
853252015Shrs	esac
854252015Shrs
855252015Shrs	for _cidr in $_arg; do
856252015Shrs		_ipaddr=${_cidr%%/*}
857252015Shrs		_plen=${_cidr##*/}
858252015Shrs		# When subnet prefix length is not specified, use /32.
859252015Shrs		case $_plen in
860252015Shrs		$_ipaddr)	_plen=32 ;;	# "/" character not found
861197139Shrs		esac
862197139Shrs
863252015Shrs		OIFS=$IFS
864252015Shrs		IFS=. set -- $_ipaddr
865252015Shrs		_range=
866252015Shrs		_iphead=
867252015Shrs		_iptail=
868252015Shrs		for _c in $@; do
869252015Shrs			case $_range:$_c in
870252015Shrs			:[0-9]*-[0-9]*)
871252015Shrs				_range=$_c
872197139Shrs			;;
873252015Shrs			:*)
874252015Shrs				_iphead="${_iphead}${_iphead:+.}${_c}"
875197139Shrs			;;
876252015Shrs			*:*)
877252015Shrs				_iptail="${_iptail}${_iptail:+.}${_c}"
878252015Shrs			;;
879252015Shrs			esac
880252015Shrs		done
881252015Shrs		IFS=$OIFS
882252015Shrs		_iplow=${_range%-*}
883252015Shrs		_iphigh=${_range#*-}
884252015Shrs
885252015Shrs		# clear netmask when removing aliases
886252015Shrs		if [ "$_action" = "-alias" ]; then
887252015Shrs			_plen=""
888252015Shrs		fi
889252015Shrs
890252015Shrs		_ipcount=$_iplow
891252015Shrs		while [ "$_ipcount" -le "$_iphigh" ]; do
892252015Shrs			_retstr="${_retstr} ${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail}${_plen:+/}${_plen}"
893252015Shrs			if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ]; then
894252015Shrs				warn "Range specification is too large (${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_iphigh}${_iptail:+.}${_iptail}).  ${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail} was processed."
895252015Shrs				break
896252015Shrs			else
897252015Shrs				_ipcount=$(($_ipcount + 1))
898252015Shrs			fi
899252015Shrs			# Forcibly set /32 for remaining aliases.
900252015Shrs			_plen=32
901252015Shrs		done
902197139Shrs	done
903197139Shrs
904252015Shrs	for _c in $_retstr; do
905253505Shrs		ifalias_expand_addr_inet $_action $_c $_exargs
906252015Shrs	done
907113674Smtm}
908100280Sgordon
909252015Shrs# ifalias_expand_addr_inet6 action addr
910252015Shrs#	Helper function for ifalias_expand_addr().  Handles IPv6.
911116029Smtm#
912252015Shrsifalias_expand_addr_inet6()
913116029Smtm{
914253505Shrs	local _action _arg _cidr _cidr_addr _exargs
915252015Shrs	local _ipaddr _plen _ipleft _ipright _iplow _iphigh _ipcount
916252015Shrs	local _ipv4part
917252015Shrs	local _retstr _c
918252015Shrs	_action=$1
919252015Shrs	_arg=$2
920253505Shrs	shift 2
921253505Shrs	_exargs=$*
922252015Shrs	_retstr=
923197139Shrs
924253505Shrs	case $_action:$_arg:$_exargs in
925253505Shrs	*:*--*:*)	return ;;	# invalid
926253505Shrs	tmp:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*)# to be expanded
927253505Shrs		_action="alias"
928253505Shrs	;;
929253505Shrs	*:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*)	# to be expanded
930253505Shrs	;;
931253505Shrs	tmp:*:*prefixlen*)	# already expanded w/ prefixlen option
932253505Shrs		echo ${_arg%/[0-9]*} $_exargs && return
933253505Shrs	;;
934253505Shrs	tmp:*:*)		# already expanded w/o prefixlen option
935253505Shrs		echo $_arg $_exargs && return
936253505Shrs	;;
937253505Shrs	*:*:*prefixlen*)	# already expanded w/ prefixlen option
938253505Shrs		echo inet6 ${_arg%/[0-9]*} $_exargs && return
939253505Shrs	;;
940253505Shrs	*:*:*)			# already expanded w/o prefixlen option
941253505Shrs		echo inet6 $_arg $_exargs && return
942253505Shrs	;;
943197139Shrs	esac
944197139Shrs
945252015Shrs	for _cidr in $_arg; do
946252015Shrs		_ipaddr="${_cidr%%/*}"
947252015Shrs		_plen="${_cidr##*/}"
948252015Shrs
949252015Shrs		case $_action:$_ipaddr:$_cidr in
950252015Shrs		-alias:*:*)		unset _plen ;;
951252015Shrs		*:$_cidr:$_ipaddr)	unset _plen ;;
952252015Shrs		esac
953252015Shrs
954252015Shrs		if [ "${_ipaddr%:*.*.*.*}" = "$_ipaddr" ]; then
955252015Shrs			# Handle !v4mapped && !v4compat addresses.
956252015Shrs
957252015Shrs			# The default prefix length is 64.
958252015Shrs			case $_ipaddr:$_cidr in
959252015Shrs			$_cidr:$_ipaddr)	_plen="64" ;;
960252015Shrs			esac
961252015Shrs			_ipleft=${_ipaddr%-*}
962252015Shrs			_ipright=${_ipaddr#*-}
963252015Shrs			_iplow=${_ipleft##*:}
964252015Shrs			_iphigh=${_ipright%%:*}
965252015Shrs			_ipleft=${_ipleft%:*}
966252015Shrs			_ipright=${_ipright#*:}
967252015Shrs
968252015Shrs			if [ "$_iphigh" = "$_ipright" ]; then
969252015Shrs				unset _ipright
970252015Shrs			else
971252015Shrs				_ipright=:$_ipright
972252015Shrs			fi
973252015Shrs
974252015Shrs			if [ -n "$_iplow" -a -n "$_iphigh" ]; then
975252015Shrs				_iplow=$((0x$_iplow))
976252015Shrs				_iphigh=$((0x$_iphigh))
977252015Shrs				_ipcount=$_iplow
978252015Shrs				while [ $_ipcount -le $_iphigh ]; do
979252015Shrs					_r=`printf "%s:%04x%s%s" \
980252015Shrs					    $_ipleft $_ipcount $_ipright \
981252015Shrs					    ${_plen:+/}$_plen`
982252015Shrs					_retstr="$_retstr $_r"
983252015Shrs					if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ]
984252015Shrs					then
985252015Shrs						warn "Range specification is too large $(printf '(%s:%04x%s-%s:%04x%s)' $_ipleft $_iplow $_ipright $_ipleft $_iphigh $_ipright). $(printf '%s:%04x%s-%s:%04x%s' $_ipleft $_iplow $_ipright $_ipleft $_ipcount $_ipright) was processed."
986252015Shrs						break
987252015Shrs					else
988252015Shrs						_ipcount=$(($_ipcount + 1))
989252015Shrs					fi
990252015Shrs				done
991252015Shrs			else
992252015Shrs				_retstr="${_ipaddr}${_plen:+/}${_plen}"
993252015Shrs			fi
994252015Shrs
995252015Shrs			for _c in $_retstr; do
996253505Shrs				ifalias_expand_addr_inet6 $_action $_c $_exargs
997252015Shrs			done
998252015Shrs		else
999252015Shrs			# v4mapped/v4compat should handle as an IPv4 alias
1000252015Shrs			_ipv4part=${_ipaddr##*:}
1001252015Shrs
1002252015Shrs			# Adjust prefix length if any.  If not, set the
1003252015Shrs			# default prefix length as 32.
1004252015Shrs			case $_ipaddr:$_cidr in
1005252015Shrs			$_cidr:$_ipaddr)	_plen=32 ;;
1006252015Shrs			*)			_plen=$(($_plen - 96)) ;;
1007252015Shrs			esac
1008252015Shrs
1009252015Shrs			_retstr=`ifalias_expand_addr_inet \
1010252015Shrs			    tmp ${_ipv4part}${_plen:+/}${_plen}`
1011252015Shrs			for _c in $_retstr; do
1012253505Shrs				ifalias_expand_addr_inet $_action $_c $_exargs
1013252015Shrs			done
1014252015Shrs		fi
1015252015Shrs	done
1016197139Shrs}
1017197139Shrs
1018252015Shrs# ifalias_af_common_handler if af action args
1019252015Shrs#	Helper function for ifalias_af_common().
1020197139Shrs#
1021252015Shrsifalias_af_common_handler()
1022197139Shrs{
1023252015Shrs	local _ret _if _af _action _args _c _tmpargs
1024252015Shrs
1025197139Shrs	_ret=1
1026252015Shrs	_if=$1
1027252015Shrs	_af=$2
1028252015Shrs	_action=$3
1029252015Shrs	shift 3
1030252015Shrs	_args=$*
1031197139Shrs
1032252015Shrs	case $_args in
1033252015Shrs	${_af}\ *)	;;
1034252015Shrs	*)	return	;;
1035252015Shrs	esac
1036252015Shrs
1037252426Shrs	# link(ether) does not support address removal.
1038252426Shrs	case $_af:$_action in
1039252426Shrs	link:-alias|ether:-alias)	return ;;
1040252426Shrs	esac
1041252426Shrs
1042252015Shrs	_tmpargs=
1043252015Shrs	for _c in $_args; do
1044252015Shrs		case $_c in
1045252015Shrs		${_af})
1046252015Shrs			case $_tmpargs in
1047252015Shrs			${_af}\ *-*)
1048252015Shrs				ifalias_af_common_handler $_if $_af $_action \
1049252015Shrs				`ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }`
1050197139Shrs			;;
1051252015Shrs			${_af}\ *)
1052252015Shrs				${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0
1053197139Shrs			;;
1054252015Shrs			esac
1055252015Shrs			_tmpargs=$_af
1056252015Shrs		;;
1057252015Shrs		*)
1058252015Shrs			_tmpargs="$_tmpargs $_c"
1059252015Shrs		;;
1060197139Shrs		esac
1061197139Shrs	done
1062252015Shrs	# Process the last component if any.
1063252015Shrs	if [ -n "$_tmpargs}" ]; then
1064252015Shrs		case $_tmpargs in
1065252015Shrs		${_af}\ *-*)
1066252015Shrs			ifalias_af_common_handler $_if $_af $_action \
1067252015Shrs			`ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }`
1068252015Shrs		;;
1069252015Shrs		${_af}\ *)
1070252015Shrs			${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0
1071252015Shrs		;;
1072252015Shrs		esac
1073252015Shrs	fi
1074197139Shrs
1075197139Shrs	return $_ret
1076197139Shrs}
1077197139Shrs
1078252015Shrs# ifalias_af_common if af action
1079252015Shrs#	Helper function for ifalias().
1080197139Shrs#
1081252015Shrsifalias_af_common()
1082197139Shrs{
1083252015Shrs	local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf
1084252015Shrs
1085197139Shrs	_ret=1
1086252015Shrs	_aliasn=
1087252015Shrs	_if=$1
1088252015Shrs	_af=$2
1089252015Shrs	_action=$3
1090197139Shrs
1091252015Shrs	# ifconfig_IF_aliasN which starts with $_af
1092197139Shrs	alias=0
1093197139Shrs	while : ; do
1094252015Shrs		ifconfig_args=`get_if_var $_if ifconfig_IF_alias${alias}`
1095252015Shrs		_iaf=
1096252015Shrs		case $ifconfig_args in
1097252015Shrs		inet\ *)	_iaf=inet ;;
1098252015Shrs		inet6\ *)	_iaf=inet6 ;;
1099252015Shrs		ipx\ *)		_iaf=ipx ;;
1100252426Shrs		link\ *)	_iaf=link ;;
1101252426Shrs		ether\ *)	_iaf=ether ;;
1102252015Shrs		esac
1103252015Shrs
1104252015Shrs		case ${_af}:${_action}:${_iaf}:"${ifconfig_args}" in
1105252015Shrs		${_af}:*:${_af}:*)
1106252015Shrs			_aliasn="$_aliasn $ifconfig_args"
1107197139Shrs			;;
1108252015Shrs		${_af}:*:"":"")
1109116029Smtm			break
1110197139Shrs			;;
1111252015Shrs		inet:alias:"":*)
1112252015Shrs			_aliasn="$_aliasn inet $ifconfig_args"
1113252015Shrs			warn "\$ifconfig_${_if}_alias${alias} needs " \
1114252015Shrs			    "\"inet\" keyword for an IPv4 address."
1115197139Shrs		esac
1116252015Shrs		alias=$(($alias + 1))
1117116029Smtm	done
1118197139Shrs
1119197139Shrs	# backward compatibility: ipv6_ifconfig_IF_aliasN.
1120252015Shrs	case $_af in
1121252015Shrs	inet6)
1122252015Shrs		alias=0
1123252015Shrs		while : ; do
1124252015Shrs			ifconfig_args=`get_if_var $_if ipv6_ifconfig_IF_alias${alias}`
1125252015Shrs			case ${_action}:"${ifconfig_args}" in
1126252015Shrs			*:"")
1127252015Shrs				break
1128197139Shrs			;;
1129252015Shrs			alias:*)
1130252015Shrs				_aliasn="${_aliasn} inet6 ${ifconfig_args}"
1131252015Shrs				warn "\$ipv6_ifconfig_${_if}_alias${alias} " \
1132252015Shrs				    "is obsolete.  Use ifconfig_$1_aliasN " \
1133252015Shrs				    "instead."
1134252015Shrs			;;
1135252015Shrs			esac
1136252015Shrs			alias=$(($alias + 1))
1137252015Shrs		done
1138252015Shrs	esac
1139252015Shrs
1140252015Shrs	# backward compatibility: ipv4_addrs_IF.
1141252015Shrs	for _tmpargs in `get_if_var $_if ipv4_addrs_IF`; do
1142252015Shrs		_aliasn="$_aliasn inet $_tmpargs"
1143252015Shrs	done
1144252015Shrs
1145252015Shrs	# Handle ifconfig_IF_aliases, ifconfig_IF_aliasN, and the others.
1146252015Shrs	_tmpargs=
1147252015Shrs	for _c in `get_if_var $_if ifconfig_IF_aliases` $_aliasn; do
1148252015Shrs		case $_c in
1149252426Shrs		inet|inet6|ipx|link|ether)
1150252015Shrs			case $_tmpargs in
1151252015Shrs			${_af}\ *)
1152252015Shrs				eval ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0
1153252015Shrs			;;
1154252015Shrs			esac
1155252015Shrs			_tmpargs=$_c
1156252015Shrs		;;
1157197139Shrs		*)
1158252015Shrs			_tmpargs="$_tmpargs $_c"
1159197139Shrs		esac
1160197139Shrs	done
1161252015Shrs	# Process the last component
1162252015Shrs	case $_tmpargs in
1163252015Shrs	${_af}\ *)
1164252015Shrs		ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0
1165252015Shrs	;;
1166252015Shrs	esac
1167197139Shrs
1168116029Smtm	return $_ret
1169116029Smtm}
1170116029Smtm
1171226652Shrs# ipv6_prefix_hostid_addr_common if action
1172226652Shrs#	Add or remove IPv6 prefix + hostid addr on the interface $if
1173226652Shrs#
1174226652Shrsipv6_prefix_hostid_addr_common()
1175197139Shrs{
1176253444Shrs	local _if _action prefix j
1177197139Shrs	_if=$1
1178226652Shrs	_action=$2
1179197139Shrs	prefix=`get_if_var ${_if} ipv6_prefix_IF`
1180197139Shrs
1181197139Shrs	if [ -n "${prefix}" ]; then
1182197139Shrs		for j in ${prefix}; do
1183252015Shrs			# The default prefixlen is 64.
1184252015Shrs			plen=${j#*/}
1185252015Shrs			case $j:$plen in
1186252015Shrs			$plen:$j)	plen=64 ;;
1187252015Shrs			*)		j=${j%/*} ;;
1188252015Shrs			esac
1189197139Shrs
1190252015Shrs			# Normalize the last part by removing ":"
1191253444Shrs			j=${j%::*}
1192252015Shrs			j=${j%:}
1193253444Shrs			${IFCONFIG_CMD} ${_if} inet6 $j:: \
1194253444Shrs				prefixlen $plen eui64 ${_action}
1195252015Shrs
1196197139Shrs			# if I am a router, add subnet router
1197197139Shrs			# anycast address (RFC 2373).
1198197139Shrs			if checkyesno ipv6_gateway_enable; then
1199252015Shrs				${IFCONFIG_CMD} ${_if} inet6 $j:: \
1200252015Shrs					prefixlen $plen ${_action} anycast
1201197139Shrs			fi
1202197139Shrs		done
1203197139Shrs	fi
1204197139Shrs}
1205197139Shrs
1206197139Shrs# ipv6_accept_rtadv_up if
1207197139Shrs#	Enable accepting Router Advertisement and send Router
1208197139Shrs#	Solicitation message
1209197139Shrsipv6_accept_rtadv_up()
1210197139Shrs{
1211197139Shrs	if ipv6_autoconfif $1; then
1212252015Shrs		${IFCONFIG_CMD} $1 inet6 accept_rtadv up
1213203433Sume		if ! checkyesno rtsold_enable; then
1214203433Sume			rtsol ${rtsol_flags} $1
1215203433Sume		fi
1216197139Shrs	fi
1217197139Shrs}
1218197139Shrs
1219197139Shrs# ipv6_accept_rtadv_down if
1220197139Shrs#	Disable accepting Router Advertisement
1221197139Shrsipv6_accept_rtadv_down()
1222197139Shrs{
1223197139Shrs	if ipv6_autoconfif $1; then
1224252015Shrs		${IFCONFIG_CMD} $1 inet6 -accept_rtadv
1225197139Shrs	fi
1226197139Shrs}
1227197139Shrs
1228113674Smtm# ifscript_up if
1229113674Smtm#	Evaluate a startup script for the $if interface.
1230113674Smtm#	It returns 0 if a script was found and processed or
1231113674Smtm#	1 if no script was found.
1232113674Smtm#
1233113674Smtmifscript_up()
1234100280Sgordon{
1235113674Smtm	if [ -r /etc/start_if.$1 ]; then
1236113674Smtm		. /etc/start_if.$1
1237113674Smtm		return 0
1238197139Shrs	else
1239197139Shrs		return 1
1240113674Smtm	fi
1241100280Sgordon}
1242100280Sgordon
1243116029Smtm# ifscript_down if
1244116029Smtm#	Evaluate a shutdown script for the $if interface.
1245116029Smtm#	It returns 0 if a script was found and processed or
1246116029Smtm#	1 if no script was found.
1247116029Smtm#
1248116029Smtmifscript_down()
1249116029Smtm{
1250116029Smtm	if [ -r /etc/stop_if.$1 ]; then
1251116029Smtm		. /etc/stop_if.$1
1252116029Smtm		return 0
1253197139Shrs	else
1254197139Shrs		return 1
1255116029Smtm	fi
1256116029Smtm}
1257116029Smtm
1258197147Shrs# clone_up
1259197147Shrs#	Create cloneable interfaces.
1260113674Smtm#
1261113674Smtmclone_up()
1262100280Sgordon{
1263256039Shrs	local _list ifn ifopt _iflist _n tmpargs
1264113674Smtm	_list=
1265253924Shrs	_iflist=$*
1266197139Shrs
1267197139Shrs	# create_args_IF
1268113674Smtm	for ifn in ${cloned_interfaces}; do
1269253924Shrs		# Parse ifn:ifopt.
1270253924Shrs		OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS
1271253924Shrs		case $_iflist in
1272253924Shrs		""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn)	;;
1273253924Shrs		*)	continue ;;
1274253924Shrs		esac
1275256039Shrs		case $ifn in
1276256039Shrs		epair[0-9]*)
1277256039Shrs			# epair(4) uses epair[0-9] for creation and
1278256039Shrs			# epair[0-9][ab] for configuration.
1279256039Shrs			#
1280256039Shrs			# Skip if ${ifn}a or ${ifn}b already exist.
1281256039Shrs			if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then
1282256039Shrs				continue
1283256039Shrs			elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then
1284256039Shrs				continue
1285256039Shrs			fi
1286256039Shrs			${IFCONFIG_CMD} ${ifn} create \
1287256039Shrs			    `get_if_var ${ifn} create_args_IF`
1288256039Shrs			if [ $? -eq 0 ]; then
1289256039Shrs				_list="$_list ${ifn}a ${ifn}b"
1290256039Shrs			fi
1291256039Shrs		;;
1292256039Shrs		*)
1293256039Shrs			# Skip if ${ifn} already exists.
1294256039Shrs			if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
1295256039Shrs				continue
1296256039Shrs			fi
1297256039Shrs			${IFCONFIG_CMD} ${ifn} create \
1298256039Shrs			    `get_if_var ${ifn} create_args_IF`
1299256039Shrs			if [ $? -eq 0 ]; then
1300256039Shrs				_list="$_list $ifn"
1301256039Shrs			fi
1302256039Shrs		esac
1303113674Smtm	done
1304253924Shrs	if [ -n "$gif_interfaces" ]; then
1305253924Shrs		warn "\$gif_interfaces is obsolete.  Use \$cloned_interfaces instead."
1306253924Shrs	fi
1307253924Shrs	for ifn in ${gif_interfaces}; do
1308253924Shrs		# Parse ifn:ifopt.
1309253924Shrs		OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS
1310253924Shrs		case $_iflist in
1311253924Shrs		""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn)	;;
1312253924Shrs		*)	continue ;;
1313253924Shrs		esac
1314253924Shrs		# Skip if ifn already exists.
1315253924Shrs		if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
1316253924Shrs			continue
1317253924Shrs		fi
1318253924Shrs		case $ifn in
1319253924Shrs		gif[0-9]*)
1320253924Shrs			${IFCONFIG_CMD} $ifn create
1321253924Shrs		;;
1322253924Shrs		*)
1323253924Shrs			_n=$(${IFCONFIG_CMD} gif create)
1324253924Shrs			${IFCONFIG_CMD} $_n name $ifn
1325253924Shrs		;;
1326253924Shrs		esac
1327253924Shrs		if [ $? -eq 0 ]; then
1328256039Shrs			_list="$_list $ifn"
1329253924Shrs		fi
1330253924Shrs		tmpargs=$(get_if_var $ifn gifconfig_IF)
1331253924Shrs		eval ifconfig_${ifn}=\"tunnel \$tmpargs\"
1332253924Shrs	done
1333256039Shrs	if [ -n "${_list# }" ]; then
1334256039Shrs		echo "Created clone interfaces: ${_list# }."
1335253924Shrs	fi
1336256039Shrs	debug "Cloned: ${_list# }"
1337113674Smtm}
1338100280Sgordon
1339197147Shrs# clone_down
1340197147Shrs#	Destroy cloned interfaces. Destroyed interfaces are echoed to
1341197147Shrs#	standard output.
1342113674Smtm#
1343113674Smtmclone_down()
1344113674Smtm{
1345256039Shrs	local _list ifn _difn ifopt _iflist _sticky
1346113674Smtm	_list=
1347253924Shrs	_iflist=$*
1348197139Shrs
1349253924Shrs	: ${cloned_interfaces_sticky:=NO}
1350253924Shrs	if checkyesno cloned_interfaces_sticky; then
1351253924Shrs		_sticky=1
1352253924Shrs	else
1353253924Shrs		_sticky=0
1354253924Shrs	fi
1355253924Shrs	for ifn in ${cloned_interfaces} ${gif_interfaces}; do
1356253924Shrs		# Parse ifn:ifopt.
1357253924Shrs		OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS
1358253924Shrs		case $ifopt:$_sticky in
1359253924Shrs		sticky:*)	continue ;;	# :sticky => not destroy
1360253924Shrs		nosticky:*)	;;		# :nosticky => destroy
1361253924Shrs		*:1)		continue ;;	# global sticky knob == 1
1362253924Shrs		esac
1363253924Shrs		case $_iflist in
1364253924Shrs		""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn)	;;
1365253924Shrs		*)	continue ;;
1366253924Shrs		esac
1367256039Shrs		case $ifn in
1368256039Shrs		epair[0-9]*)
1369256039Shrs			# Note: epair(4) uses epair[0-9] for removal and
1370256039Shrs			# epair[0-9][ab] for configuration.
1371256039Shrs			#
1372256039Shrs			# Skip if both of ${ifn}a and ${ifn}b do not exist.
1373256039Shrs			if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then
1374256039Shrs				_difn=${ifn}a
1375256039Shrs			elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then
1376256039Shrs				_difn=${ifn}b
1377256039Shrs			else
1378256039Shrs				continue
1379256039Shrs			fi
1380256039Shrs			${IFCONFIG_CMD} -n $_difn destroy
1381256039Shrs			if [ $? -eq 0 ]; then
1382256039Shrs				_list="$_list ${ifn}a ${ifn}b"
1383256039Shrs			fi
1384256039Shrs		;;
1385256039Shrs		*)
1386256039Shrs			# Skip if ifn does not exist.
1387256039Shrs			if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
1388256039Shrs				continue
1389256039Shrs			fi
1390256039Shrs			${IFCONFIG_CMD} -n ${ifn} destroy
1391256039Shrs			if [ $? -eq 0 ]; then
1392256039Shrs				_list="$_list $ifn"
1393256039Shrs			fi
1394256039Shrs		;;
1395256039Shrs		esac
1396113674Smtm	done
1397256039Shrs	if [ -n "${_list# }" ]; then
1398256039Shrs		echo "Destroyed clone interfaces: ${_list# }."
1399253924Shrs	fi
1400256039Shrs	debug "Destroyed clones: ${_list# }"
1401100280Sgordon}
1402100280Sgordon
1403197147Shrs# childif_create
1404197147Shrs#	Create and configure child interfaces.  Return 0 if child
1405197147Shrs#	interfaces are created.
1406178356Ssam#
1407178356Ssamchildif_create()
1408178356Ssam{
1409201215Sjhb	local cfg child child_vlans child_wlans create_args debug_flags ifn i
1410178356Ssam	cfg=1
1411178356Ssam	ifn=$1
1412178356Ssam
1413178527Sbrooks	# Create wireless interfaces
1414178527Sbrooks	child_wlans=`get_if_var $ifn wlans_IF`
1415178527Sbrooks
1416178527Sbrooks	for child in ${child_wlans}; do
1417183517Sbrooks		create_args="wlandev $ifn `get_if_var $child create_args_IF`"
1418189759Sbrooks		debug_flags="`get_if_var $child wlandebug_IF`"
1419189759Sbrooks
1420178356Ssam		if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then
1421252015Shrs			${IFCONFIG_CMD} $child create ${create_args} && cfg=0
1422189759Sbrooks			if [ -n "${debug_flags}" ]; then
1423189759Sbrooks				wlandebug -i $child ${debug_flags}
1424189759Sbrooks			fi
1425178356Ssam		else
1426252015Shrs			i=`${IFCONFIG_CMD} wlan create ${create_args}`
1427189759Sbrooks			if [ -n "${debug_flags}" ]; then
1428189759Sbrooks				wlandebug -i $i ${debug_flags}
1429189759Sbrooks			fi
1430252015Shrs			${IFCONFIG_CMD} $i name $child && cfg=0
1431178356Ssam		fi
1432188118Sthompsa		if autoif $child; then
1433188118Sthompsa			ifn_start $child
1434188118Sthompsa		fi
1435178356Ssam	done
1436178356Ssam
1437201215Sjhb	# Create vlan interfaces
1438201215Sjhb	child_vlans=`get_if_var $ifn vlans_IF`
1439201215Sjhb
1440201215Sjhb	if [ -n "${child_vlans}" ]; then
1441201215Sjhb		load_kld if_vlan
1442201215Sjhb	fi
1443201215Sjhb
1444201215Sjhb	for child in ${child_vlans}; do
1445201215Sjhb		if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then
1446201215Sjhb			child="${ifn}.${child}"
1447201215Sjhb			create_args=`get_if_var $child create_args_IF`
1448252015Shrs			${IFCONFIG_CMD} $child create ${create_args} && cfg=0
1449201215Sjhb		else
1450201215Sjhb			create_args="vlandev $ifn `get_if_var $child create_args_IF`"
1451201215Sjhb			if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then
1452252015Shrs				${IFCONFIG_CMD} $child create ${create_args} && cfg=0
1453201215Sjhb			else
1454252015Shrs				i=`${IFCONFIG_CMD} vlan create ${create_args}`
1455252015Shrs				${IFCONFIG_CMD} $i name $child && cfg=0
1456201215Sjhb			fi
1457201215Sjhb		fi
1458201215Sjhb		if autoif $child; then
1459201215Sjhb			ifn_start $child
1460201215Sjhb		fi
1461201215Sjhb	done
1462201215Sjhb
1463179001Sbrooks	return ${cfg}
1464178356Ssam}
1465178356Ssam
1466197147Shrs# childif_destroy
1467197147Shrs#	Destroy child interfaces.
1468178356Ssam#
1469178356Ssamchildif_destroy()
1470178356Ssam{
1471201215Sjhb	local cfg child child_vlans child_wlans ifn
1472197139Shrs	cfg=1
1473178356Ssam
1474201216Sjhb	child_wlans=`get_if_var $ifn wlans_IF`
1475178527Sbrooks	for child in ${child_wlans}; do
1476201215Sjhb		if ! ifexists $child; then
1477201215Sjhb			continue
1478201215Sjhb		fi
1479252015Shrs		${IFCONFIG_CMD} -n $child destroy && cfg=0
1480178356Ssam	done
1481197139Shrs
1482201215Sjhb	child_vlans=`get_if_var $ifn vlans_IF`
1483201215Sjhb	for child in ${child_vlans}; do
1484201215Sjhb		if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then
1485201215Sjhb			child="${ifn}.${child}"
1486201215Sjhb		fi
1487201215Sjhb		if ! ifexists $child; then
1488201215Sjhb			continue
1489201215Sjhb		fi
1490252015Shrs		${IFCONFIG_CMD} -n $child destroy && cfg=0
1491201215Sjhb	done
1492201215Sjhb
1493197139Shrs	return ${cfg}
1494178356Ssam}
1495178356Ssam
1496197147Shrs# ng_mkpeer
1497197147Shrs#	Create netgraph nodes.
1498166583Sflz#
1499197147Shrsng_mkpeer()
1500197147Shrs{
1501166583Sflz	ngctl -f - 2> /dev/null <<EOF
1502166583Sflzmkpeer $*
1503166583Sflzmsg dummy nodeinfo
1504166583SflzEOF
1505166583Sflz}
1506166583Sflz
1507197147Shrs# ng_create_one
1508197147Shrs#	Create netgraph nodes.
1509197147Shrs#
1510197147Shrsng_create_one()
1511197147Shrs{
1512197139Shrs	local t
1513197139Shrs
1514166583Sflz	ng_mkpeer $* | while read line; do
1515166583Sflz		t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'`
1516166583Sflz		if [ -n "${t}" ]; then
1517166583Sflz			echo ${t}
1518166583Sflz			return
1519166583Sflz		fi
1520166583Sflz	done
1521166583Sflz}
1522166583Sflz
1523166583Sflz# ng_fec_create ifn
1524197147Shrs#	Configure Fast EtherChannel for interface $ifn. Returns 0 if
1525197147Shrs#	FEC arguments were found and configured; returns !0 otherwise.
1526197139Shrsng_fec_create()
1527197139Shrs{
1528166583Sflz	 local req_iface iface bogus
1529166583Sflz	 req_iface="$1"
1530166583Sflz
1531166583Sflz	 ngctl shutdown ${req_iface}: > /dev/null 2>&1
1532166583Sflz
1533166583Sflz	 bogus=""
1534166583Sflz	 while true; do
1535166583Sflz		 iface=`ng_create_one fec dummy fec`
1536166583Sflz		 if [ -z "${iface}" ]; then
1537166583Sflz			 exit 2
1538166583Sflz		 fi
1539166583Sflz		 if [ "${iface}" = "${req_iface}" ]; then
1540166583Sflz			 break
1541166583Sflz		 fi
1542166583Sflz		 bogus="${bogus} ${iface}"
1543166583Sflz	 done
1544166583Sflz
1545166583Sflz	 for iface in ${bogus}; do
1546166583Sflz		 ngctl shutdown ${iface}:
1547166583Sflz	 done
1548166583Sflz}
1549166583Sflz
1550197147Shrs# fec_up
1551197147Shrs#	Create Fast EtherChannel interfaces.
1552197147Shrsfec_up()
1553197147Shrs{
1554197139Shrs	local i j
1555197139Shrs
1556166583Sflz	for i in ${fec_interfaces}; do
1557166583Sflz		ng_fec_create $i
1558166583Sflz		for j in `get_if_var $i fecconfig_IF`; do
1559166583Sflz			case ${j} in
1560100282Sdougb			'')
1561100282Sdougb				continue
1562100282Sdougb				;;
1563100282Sdougb			*)
1564166583Sflz				ngctl msg ${i}: add_iface "\"${j}\""
1565100282Sdougb				;;
1566100282Sdougb			esac
1567100282Sdougb		done
1568166583Sflz	done
1569100282Sdougb}
1570100282Sdougb
1571113674Smtm# ipx_up ifn
1572197147Shrs#	Configure any IPX addresses for interface $ifn. Returns 0 if
1573197147Shrs#	IPX arguments were found and configured; returns 1 otherwise.
1574113674Smtm#
1575113674Smtmipx_up()
1576100280Sgordon{
1577197139Shrs	local ifn
1578113674Smtm	ifn="$1"
1579197139Shrs
1580197139Shrs	# ifconfig_IF_ipx
1581197139Shrs	ifconfig_args=`_ifconfig_getargs $ifn ipx`
1582113674Smtm	if [ -n "${ifconfig_args}" ]; then
1583252015Shrs		${IFCONFIG_CMD} ${ifn} ${ifconfig_args}
1584113674Smtm		return 0
158585831Sdes	fi
1586197139Shrs
1587113674Smtm	return 1
1588113674Smtm}
158985831Sdes
1590116029Smtm# ipx_down ifn
1591116029Smtm#	Remove IPX addresses for interface $ifn. Returns 0 if IPX
1592116029Smtm#	addresses were found and unconfigured. It returns 1, otherwise.
1593113674Smtm#
1594116029Smtmipx_down()
1595116029Smtm{
1596197139Shrs	local _if _ifs _ret ipxList oldifs _ipx
1597197139Shrs	_if=$1
1598116100Smtm	_ifs="^"
1599116100Smtm	_ret=1
1600252015Shrs	ipxList="`${IFCONFIG_CMD} ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`"
1601197139Shrs	oldifs="$IFS"
1602116100Smtm
1603116100Smtm	IFS="$_ifs"
1604116100Smtm	for _ipx in $ipxList ; do
1605116100Smtm		# get rid of extraneous line
1606116100Smtm		[ -z "$_ipx" ] && break
1607116100Smtm
1608116100Smtm		_ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'`
1609116100Smtm
1610116100Smtm		IFS="$oldifs"
1611252015Shrs		${IFCONFIG_CMD} ${_if} ${_ipx} delete
1612116100Smtm		IFS="$_ifs"
1613116100Smtm		_ret=0
1614116100Smtm	done
1615116100Smtm	IFS="$oldifs"
1616116100Smtm
1617116100Smtm	return $_ret
1618116029Smtm}
1619116029Smtm
1620253924Shrs# ifnet_rename [ifname]
1621253924Shrs#	Rename interfaces if ifconfig_IF_name is defined.
1622116029Smtm#
1623137070Spjdifnet_rename()
1624137070Spjd{
1625197139Shrs	local _if _ifname
1626137070Spjd
1627197139Shrs	# ifconfig_IF_name
1628253924Shrs	for _if in ${*:-$(${IFCONFIG_CMD} -l)}; do
1629157706Sbrooks		_ifname=`get_if_var $_if ifconfig_IF_name`
1630137070Spjd		if [ ! -z "$_ifname" ]; then
1631252015Shrs			${IFCONFIG_CMD} $_if name $_ifname
1632137070Spjd		fi
1633137070Spjd	done
1634197139Shrs
1635137070Spjd	return 0
1636137070Spjd}
1637137070Spjd
1638113674Smtm# list_net_interfaces type
1639113674Smtm#	List all network interfaces. The type of interface returned
1640113674Smtm#	can be controlled by the type argument. The type
1641113674Smtm#	argument can be any of the following:
1642197147Shrs#		nodhcp	- all interfaces, excluding DHCP configured interfaces
1643197147Shrs#		dhcp	- list only DHCP configured interfaces
1644197139Shrs#		noautoconf	- all interfaces, excluding IPv6 Stateless
1645197139Shrs#				  Address Autoconf configured interfaces
1646197139Shrs#		autoconf	- list only IPv6 Stateless Address Autoconf
1647197139Shrs#				  configured interfaces
1648113674Smtm#	If no argument is specified all network interfaces are output.
1649134429Syar#	Note that the list will include cloned interfaces if applicable.
1650134429Syar#	Cloned interfaces must already exist to have a chance to appear
1651134429Syar#	in the list if ${network_interfaces} is set to `auto'.
1652113674Smtm#
1653113674Smtmlist_net_interfaces()
1654113674Smtm{
1655197139Shrs	local type _tmplist _list _autolist _lo _if
1656113674Smtm	type=$1
165765532Snectar
1658149726Sbrooks	# Get a list of ALL the interfaces and make lo0 first if it's there.
165951231Ssheldonh	#
1660197139Shrs	_tmplist=
166151231Ssheldonh	case ${network_interfaces} in
166251231Ssheldonh	[Aa][Uu][Tt][Oo])
1663252015Shrs		_autolist="`${IFCONFIG_CMD} -l`"
1664149726Sbrooks		_lo=
1665149401Sbrooks		for _if in ${_autolist} ; do
1666149401Sbrooks			if autoif $_if; then
1667149726Sbrooks				if [ "$_if" = "lo0" ]; then
1668149726Sbrooks					_lo="lo0 "
1669149726Sbrooks				else
1670197139Shrs					_tmplist="${_tmplist} ${_if}"
1671149726Sbrooks				fi
1672149401Sbrooks			fi
1673149401Sbrooks		done
1674197139Shrs		_tmplist="${_lo}${_tmplist# }"
1675256039Shrs	;;
167683677Sbrooks	*)
1677256039Shrs		for _if in ${network_interfaces} ${cloned_interfaces}; do
1678256039Shrs			# epair(4) uses epair[0-9] for creation and
1679256039Shrs			# epair[0-9][ab] for configuration.
1680256039Shrs			case $_if in
1681256039Shrs			epair[0-9]*)
1682256039Shrs				_tmplist="$_tmplist ${_if}a ${_if}b"
1683256039Shrs			;;
1684256039Shrs			*)
1685256039Shrs				_tmplist="$_tmplist $_if"
1686256039Shrs			;;
1687256039Shrs			esac
1688256039Shrs		done
1689256039Shrs		#
1690196478Sdougb		# lo0 is effectively mandatory, so help prevent foot-shooting
1691196478Sdougb		#
1692196478Sdougb		case "$_tmplist" in
1693256039Shrs		lo0|'lo0 '*|*' lo0'|*' lo0 '*)
1694256039Shrs			# This is fine, do nothing
1695256039Shrs			_tmplist="${_tmplist# }"
1696256039Shrs		;;
1697256039Shrs		*)
1698256039Shrs			_tmplist="lo0 ${_tmplist# }"
1699256039Shrs		;;
1700196478Sdougb		esac
1701256039Shrs	;;
170251231Ssheldonh	esac
170349122Sbrian
1704197139Shrs	_list=
1705197139Shrs	case "$type" in
1706197139Shrs	nodhcp)
1707197139Shrs		for _if in ${_tmplist} ; do
1708197139Shrs			if ! dhcpif $_if && \
1709197139Shrs			   [ -n "`_ifconfig_getargs $_if`" ]; then
1710197139Shrs				_list="${_list# } ${_if}"
1711197147Shrs			fi
1712197139Shrs		done
1713256039Shrs	;;
1714197139Shrs	dhcp)
1715197147Shrs		for _if in ${_tmplist} ; do
1716197147Shrs			if dhcpif $_if; then
1717197139Shrs				_list="${_list# } ${_if}"
1718197147Shrs			fi
1719197147Shrs		done
1720256039Shrs	;;
1721197139Shrs	noautoconf)
1722197139Shrs		for _if in ${_tmplist} ; do
1723197139Shrs			if ! ipv6_autoconfif $_if && \
1724197139Shrs			   [ -n "`_ifconfig_getargs $_if ipv6`" ]; then
1725197139Shrs				_list="${_list# } ${_if}"
1726197139Shrs			fi
1727197139Shrs		done
1728256039Shrs	;;
1729197139Shrs	autoconf)
1730197139Shrs		for _if in ${_tmplist} ; do
1731197139Shrs			if ipv6_autoconfif $_if; then
1732197139Shrs				_list="${_list# } ${_if}"
1733197139Shrs			fi
1734197139Shrs		done
1735256039Shrs	;;
1736197139Shrs	*)
1737197139Shrs		_list=${_tmplist}
1738256039Shrs	;;
1739113674Smtm	esac
1740197139Shrs
1741197139Shrs	echo $_list
1742197139Shrs
1743130151Sschweikh	return 0
174425184Sjkh}
1745114942Sume
1746179003Sbrooks# get_default_if -address_family
1747179003Sbrooks#	Get the interface of the default route for the given address family.
1748179003Sbrooks#	The -address_family argument must be suitable passing to route(8).
1749179003Sbrooks#
1750179003Sbrooksget_default_if()
1751179003Sbrooks{
1752197139Shrs	local routeget oldifs defif line
1753197139Shrs	defif=
1754179003Sbrooks	oldifs="$IFS"
1755179003Sbrooks	IFS="
1756179003Sbrooks"
1757197139Shrs	for line in `route -n get $1 default 2>/dev/null`; do
1758179003Sbrooks		case $line in
1759179003Sbrooks		*interface:*)
1760179003Sbrooks			defif=${line##*: }
1761179003Sbrooks			;;
1762179003Sbrooks		esac
1763179003Sbrooks	done
1764179003Sbrooks	IFS=${oldifs}
1765179003Sbrooks
1766179003Sbrooks	echo $defif
1767179003Sbrooks}
1768179003Sbrooks
1769197147Shrs# hexdigit arg
1770197147Shrs#	Echo decimal number $arg (single digit) in hexadecimal format.
1771114942Sumehexdigit()
1772114942Sume{
1773221884Sjilles	printf '%x\n' "$1"
1774114942Sume}
1775114942Sume
1776197147Shrs# hexprint arg
1777197147Shrs#	Echo decimal number $arg (multiple digits) in hexadecimal format.
1778114942Sumehexprint()
1779114942Sume{
1780221884Sjilles	printf '%x\n' "$1"
1781114942Sume}
1782114942Sume
1783196436Sdougbis_wired_interface()
1784196436Sdougb{
1785196436Sdougb	local media
1786196436Sdougb
1787252015Shrs	case `${IFCONFIG_CMD} $1 2>/dev/null` in
1788196436Sdougb	*media:?Ethernet*) media=Ethernet ;;
1789196436Sdougb	esac
1790196436Sdougb
1791196436Sdougb	test "$media" = "Ethernet"
1792196436Sdougb}
1793196436Sdougb
1794197147Shrs# network6_getladdr if [flag]
1795197147Shrs#	Echo link-local address from $if if any.
1796197147Shrs#	If flag is defined, tentative ones will be excluded.
1797114942Sumenetwork6_getladdr()
1798114942Sume{
1799252015Shrs	local _if _flag proto addr rest
1800252015Shrs	_if=$1
1801252015Shrs	_flag=$2
1802252015Shrs
1803252015Shrs	${IFCONFIG_CMD} $_if 2>/dev/null | while read proto addr rest; do
1804252015Shrs		case "${proto}/${addr}/${_flag}/${rest}" in
1805252015Shrs		inet6/fe80::*//*)
1806252015Shrs			echo ${addr}
1807252015Shrs		;;
1808252015Shrs		inet6/fe80:://*tentative*)	# w/o flag
1809252015Shrs			sleep `${SYSCTL_N} net.inet6.ip6.dad_count`
1810252015Shrs			network6_getladdr $_if $_flags
1811252015Shrs		;;
1812252015Shrs		inet6/fe80::/*/*tentative*)	# w/ flag
1813252015Shrs			echo ${addr}
1814252015Shrs		;;
1815252015Shrs		*)
1816252015Shrs			continue
1817252015Shrs		;;
1818114942Sume		esac
1819252015Shrs
1820252015Shrs		return
1821114942Sume	done
1822114942Sume}
1823