etc/network.subr: enhance wlan initialization
[dragonfly.git] / etc / network.subr
CommitLineData
9c600e7d
MD
1#
2# Copyright (c) 2003 The FreeBSD Project. All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions
6# are met:
7# 1. Redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer.
9# 2. Redistributions in binary form must reproduce the above copyright
10# notice, this list of conditions and the following disclaimer in the
11# documentation and/or other materials provided with the distribution.
12#
13# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
14# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
17# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23# SUCH DAMAGE.
24#
f26c267a 25# $FreeBSD: src/etc/network.subr,v 1.163 2005/06/30 04:52:47 brooks Exp $
9c600e7d
MD
26#
27
28#
29# Subroutines commonly used from network startup scripts.
e4b0f1d1 30# Requires that /etc/rc.subr be loaded first.
9c600e7d
MD
31#
32
33# ifconfig_up if
34# Evaluate ifconfig(8) arguments for interface $if and
35# run ifconfig(8) with those arguments. It returns 0 if
36# arguments were found and executed or 1 if the interface
f26c267a
SW
37# had no arguments. Pseudo arguments DHCP and WPA are handled
38# here.
9c600e7d
MD
39#
40ifconfig_up()
41{
e4b0f1d1 42 local _cfg ifconfig_args
f26c267a
SW
43 _cfg=1
44
45 ifconfig_args=`ifconfig_getargs $1`
9c600e7d
MD
46 if [ -n "${ifconfig_args}" ]; then
47 ifconfig $1 ${ifconfig_args}
5ad36ff1 48 ifconfig $1 up
f26c267a 49 _cfg=0
9c600e7d 50 fi
f26c267a
SW
51
52 if wpaif $1; then
5ad36ff1 53 ifconfig $1 up
f26c267a 54 /etc/rc.d/wpa_supplicant start $1
e9136cbf
AL
55 # NOTE: wpa_supplicant(8) needs to control the interface's
56 # state in order to perform the SSID scan. But
57 # dhcpcd(8), which may be started by the "dhcp_client"
58 # below, can race against wpa_supplicant(8) and modify
59 # the interface's state, breaking the SSID scan and
60 # preventing the SSID association.
61 # Insert a small delay here to workaround the issue.
62 sleep 1
f26c267a
SW
63 _cfg=0 # XXX: not sure this should count
64 fi
65
66 if dhcpif $1; then
817cf585 67 /etc/rc.d/dhcp_client start $1
f26c267a
SW
68 _cfg=0
69 fi
70
71 return $_cfg
9c600e7d
MD
72}
73
74# ifconfig_down if
75# Remove all inet entries from the $if interface. It returns
76# 0 if inet entries were found and removed. It returns 1 if
77# no entries were found or they could not be removed.
78#
79ifconfig_down()
80{
e4b0f1d1
AL
81 local _cfg _ifs oldifs _inet inetList
82
9c600e7d
MD
83 [ -z "$1" ] && return 1
84 _ifs="^"
f26c267a 85 _cfg=1
9c600e7d
MD
86
87 inetList="`ifconfig $1 | grep 'inet ' | tr "\n" "$_ifs"`"
88
89 oldifs="$IFS"
90 IFS="$_ifs"
91 for _inet in $inetList ; do
92 # get rid of extraneous line
93 [ -z "$_inet" ] && break
94
95 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'`
96
97 IFS="$oldifs"
98 ifconfig $1 ${_inet} delete
99 IFS="$_ifs"
f26c267a 100 _cfg=0
9c600e7d
MD
101 done
102 IFS="$oldifs"
103
f26c267a
SW
104 if wpaif $1; then
105 /etc/rc.d/wpa_supplicant stop $1
106 fi
107
108 if dhcpif $1; then
817cf585 109 /etc/rc.d/dhcp_client stop $1
f26c267a
SW
110 _cfg=0
111 fi
112
5ad36ff1
AL
113 if ifexists $1; then
114 ifconfig $1 down
115 _cfg=0
116 fi
117
f26c267a
SW
118 return $_cfg
119}
120
d86e211f
AH
121# get_if_var if var [default]
122# Return the value of the pseudo-hash corresponding to $if where
123# $var is a string containg the sub-string "IF" which will be
124# replaced with $if after the characters defined in _punct are
125# replaced with '_'. If the variable is unset, replace it with
126# $default if given.
e4b0f1d1 127#
d86e211f
AH
128get_if_var()
129{
130 local _if _punct_c _punct _var _default prefix suffix
131
132 if [ $# -ne 2 -a $# -ne 3 ]; then
133 err 3 'USAGE: get_if_var name var [default]'
134 fi
135
136 _if=$1
137 _punct=". - / +"
138 for _punct_c in $_punct; do
139 _if=`ltr ${_if} ${_punct_c} '_'`
140 done
141 _var=$2
142 _default=$3
143
144 prefix=${_var%%IF*}
145 suffix=${_var##*IF}
146 eval echo \${${prefix}${_if}${suffix}-${_default}}
147}
148
8cd2e074 149# _ifconfig_getargs if [af]
f26c267a 150# Echos the arguments for the supplied interface to stdout.
e4b0f1d1
AL
151# Returns 1 if no interface is specified.
152# In general, the ifconfig_getargs() below should be used outside
153# this file.
154#
f26c267a
SW
155_ifconfig_getargs()
156{
e4b0f1d1
AL
157 local _if _ifn _af _args
158
f26c267a 159 _ifn=$1
8cd2e074
AL
160 _af=${2:+${2}_}
161
f26c267a
SW
162 if [ -z "$_ifn" ]; then
163 return 1
164 fi
165
8cd2e074 166 _args=`get_if_var $_ifn ${_af}ifconfig_IF`
f26c267a
SW
167 if [ -z "$_args" -a -n "${pccard_ifconfig}" ]; then
168 for _if in ${removable_interfaces} ; do
169 if [ "$_if" = "$_ifn" ] ; then
170 _args=${pccard_ifconfig}
171 break
172 fi
173 done
174 fi
175
176 echo $_args
177}
178
8cd2e074 179# ifconfig_getargs if [af]
e4b0f1d1 180# Takes the result from _ifconfig_getargs() and removes pseudo
f26c267a 181# args such as DHCP and WPA.
e4b0f1d1 182#
f26c267a
SW
183ifconfig_getargs()
184{
e4b0f1d1
AL
185 local _tmpargs _arg _args is_optarg
186
8cd2e074 187 _tmpargs=`_ifconfig_getargs $1 $2`
f26c267a
SW
188 if [ $? -eq 1 ]; then
189 return 1
190 fi
191 _args=
192
1f03f592 193 is_optarg=no
f26c267a 194 for _arg in $_tmpargs; do
1f03f592
SW
195 if [ "$is_optarg" = "no" ]; then
196 case $_arg in
197 [Dd][Hh][Cc][Pp])
198 ;;
199 [Ww][Pp][Aa])
200 ;;
201 *)
202 _args="$_args $_arg"
203 case $_arg in
204 authmode)
205 is_optarg=yes
206 ;;
207 esac
208 ;;
209 esac
210 else
f26c267a 211 _args="$_args $_arg"
1f03f592
SW
212 is_optarg=no
213 fi
f26c267a
SW
214 done
215
216 echo $_args
217}
218
da4dd514
AL
219# ipv6if if
220# Returns 0 if the interface should be configured for IPv6 and
221# 1 otherwise.
e4b0f1d1 222#
da4dd514
AL
223ipv6if()
224{
225 local _if _tmpargs
226 _if=$1
227
228 # lo0 is always IPv6-enabled
e4b0f1d1 229 if [ "$_if" = "lo0" ]; then
da4dd514 230 return 0
e4b0f1d1 231 fi
da4dd514
AL
232
233 case ${ipv6_enable} in
234 [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
235 return 1
236 ;;
237 esac
238
239 case "${ipv6_network_interfaces}" in
240 $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo])
241 # True if $ipv6_ifconfig_IF is defined.
242 _tmpargs=`_ifconfig_getargs $_if ipv6`
243 if [ -n "${_tmpargs}" ]; then
244 return 0
245 fi
246
247 # True if $ipv6_prefix_IF is defined.
248 _tmpargs=`get_if_var $_if ipv6_prefix_IF`
249 if [ -n "${_tmpargs}" ]; then
250 return 0
251 fi
252
253 ;;
254 esac
255
256 return 1
257}
258
329743de
AL
259# dhcpif if [ipv4|ipv6]
260# Returns 0 if the interface needs DHCP for IPv4/IPv6 and 1 otherwise.
261# If the second argument is "ipv4" (or "ipv6"), then only IPv4 (or
262# IPv6) is checked, otherwise both are checked.
e4b0f1d1 263#
f26c267a
SW
264dhcpif()
265{
329743de
AL
266 local _tmpargs _arg _if _af
267 _if=$1
268 _af=$2
269
270 if [ -z "$_af" -o "$_af" = "ipv4" ]; then
271 _tmpargs=`_ifconfig_getargs $_if`
272 for _arg in $_tmpargs; do
273 case $_arg in
274 [Dd][Hh][Cc][Pp])
275 return 0
276 ;;
277 esac
278 done
279 fi
280
281 if [ -z "$_af" -o "$_af" = "ipv6" ] && ipv6if $_if; then
282 _tmpargs=`_ifconfig_getargs $_if ipv6`
283 for _arg in $_tmpargs; do
284 case $_arg in
285 [Dd][Hh][Cc][Pp])
286 return 0
287 ;;
288 esac
289 done
290 fi
291
f26c267a
SW
292 return 1
293}
294
295# wpaif if
296# Returns 0 if the interface is a WPA interface and 1 otherwise.
e4b0f1d1 297#
f26c267a
SW
298wpaif()
299{
e4b0f1d1
AL
300 local _tmpargs _arg is_optarg
301
f26c267a 302 _tmpargs=`_ifconfig_getargs $1`
1f03f592 303 is_optarg=no
f26c267a 304 for _arg in $_tmpargs; do
1f03f592
SW
305 if [ "$is_optarg" = "no" ]; then
306 case $_arg in
307 [Ww][Pp][Aa])
308 return 0
309 ;;
310 authmode)
311 is_optarg=yes
312 ;;
313 esac
314 else
315 is_optarg=no
316 fi
f26c267a 317 done
e4b0f1d1 318
f26c267a 319 return 1
9c600e7d
MD
320}
321
cc419283
AL
322# ifexists if
323# Returns 0 if the interface exists and 1 otherwise.
e4b0f1d1 324#
cc419283
AL
325ifexists()
326{
327 [ -z "$1" ] && return 1
e4b0f1d1 328 ifconfig -n $1 >/dev/null 2>&1
cc419283
AL
329}
330
3b4e0f2a
AL
331# ifalias_common if action [ipv6]
332# Helper function for ifalias_up() and ifalias_down().
333# The $action argument can be either "alias" (to add an
334# alias) or "-alias" (to remove an alias).
335# Returns 0 if at least one alias was added/removed or
9c600e7d
MD
336# 1 if there were none.
337#
3b4e0f2a 338ifalias_common()
9c600e7d 339{
3b4e0f2a
AL
340 local _if _action _af _af2 _ret _var _args _alias
341 _if=$1
342 _action=$2
343 _af=$3
e4b0f1d1 344
9c600e7d 345 _ret=1
3b4e0f2a 346 _alias=0
9c600e7d 347 while : ; do
3b4e0f2a
AL
348 if [ "${_af}" = "ipv6" ]; then
349 _af2="inet6"
350 _var="ipv6_ifconfig_IF_alias${_alias}"
9c600e7d 351 else
3b4e0f2a
AL
352 _af2="inet"
353 _var="ifconfig_IF_alias${_alias}"
354 fi
355 _args=`get_if_var $_if $_var`
356 _args="${_args#${_af2} }"
357 if [ -z "${_args}" ]; then
9c600e7d
MD
358 break
359 fi
3b4e0f2a
AL
360 ifconfig $_if $_af2 $_args $_action
361 _alias=$((${_alias} + 1))
362 _ret=0
9c600e7d
MD
363 done
364 return $_ret
365}
366
3b4e0f2a
AL
367# ifalias_up if [ipv6]
368# Configure IPv4 aliases for network interface $if or
369# IPv6 aliases if the second argument is "ipv6".
370# It returns 0 if at least one alias was configured or
371# 1 if there were none.
372#
373ifalias_up()
374{
375 ifalias_common $1 alias $2
376}
377
378# ifalias_down if [ipv6]
379# Remove IPv4 aliases for network interface $if or
380# IPv6 aliases if the second argument is "ipv6".
9c600e7d
MD
381# It returns 0 if at least one alias was removed or
382# 1 if there were none.
383#
384ifalias_down()
385{
3b4e0f2a 386 ifalias_common $1 -alias $2
9c600e7d
MD
387}
388
389# ifscript_up if
390# Evaluate a startup script for the $if interface.
391# It returns 0 if a script was found and processed or
392# 1 if no script was found.
393#
394ifscript_up()
395{
396 if [ -r /etc/start_if.$1 ]; then
397 . /etc/start_if.$1
398 return 0
399 fi
400 return 1
401}
402
403# ifscript_down if
404# Evaluate a shutdown script for the $if interface.
405# It returns 0 if a script was found and processed or
406# 1 if no script was found.
407#
408ifscript_down()
409{
410 if [ -r /etc/stop_if.$1 ]; then
411 . /etc/stop_if.$1
412 return 0
413 fi
414 return 1
415}
416
69dc5784
DF
417# wlan_get_unused
418# walk through net.wlan and find unused device that can be created
419#
420wlan_get_unused()
421{
422 local idx
423
424 idx=0
425
426 while : ; do
427 if ! ${SYSCTL_N} -q net.wlan.${idx}.%parent >/dev/null; then
428 echo "wlan${idx}"
429 break
430 fi
431 idx=$((${idx} + 1))
432 done
433}
434
435# wlan_is_parent
436# check if given interface is parent for any existing wlan device
437#
438wlan_is_parent()
439{
440 sysctl -q net.wlan | grep -q "%parent: ${1}"
441}
442
3928a593
AL
443# wlan_up
444# Create IEEE 802.11 interfaces.
445#
446wlan_up()
447{
448 local _prefix _list parent child child_wlans create_args debug_flags
449 _prefix=
450 _list=
451
69dc5784
DF
452 local _rcconf _auto
453 _rcconf=""
454 _auto=""
455
456 # Order detected devices so that interfaces configured via rc.conf are
457 # created first, and then all other devices are automatically assigned
3928a593 458 for parent in `${SYSCTL_N} -q net.wlan.devices`; do
69dc5784
DF
459 child_wlans=`get_if_var $parent wlans_IF`
460 if [ -n "${child_wlans}" ]; then
461 _rcconf="${_rcconf} ${parent}"
462 else
463 _auto="${_auto} ${parent}"
464 fi
465 done
466
467 for parent in ${_rcconf} ${_auto}; do
468 if wlan_is_parent $parent; then
469 continue
470 fi
3928a593
AL
471 # Parse wlans_$parent="$child ..."
472 child_wlans=`get_if_var $parent wlans_IF`
69dc5784
DF
473 # Or find first unused wlan device to create
474 if [ -z "${child_wlans}" ]; then
475 child_wlans=`wlan_get_unused`
476 fi
3928a593
AL
477 for child in ${child_wlans}; do
478 if ifexists $child; then
479 continue
480 fi
481
482 create_args="wlandev $parent `get_if_var $child create_args_IF`"
483 debug_flags="`get_if_var $child wlandebug_IF`"
484 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then
485 ifconfig $child create ${create_args}
486 else
487 ifconfig wlan create ${create_args} name $child
488 fi
489 if [ $? -eq 0 ]; then
490 _list="${_list}${_prefix}${child}"
491 [ -z "$_prefix" ] && _prefix=' '
492 fi
493 if [ -n "${debug_flags}" ]; then
494 wlandebug -i $child ${debug_flags}
495 fi
496 done
497 done
498
499 if [ -n "${_list}" ]; then
500 echo "Created wlan interfaces: ${_list}"
501 fi
502 debug "Created wlan interfaces: ${_list}"
503}
504
505# wlan_down
506# Destroy IEEE 802.11 interfaces.
507#
508wlan_down()
509{
510 local _prefix _list parent child child_wlans
511 _prefix=
512 _list=
513
514 for parent in `${SYSCTL_N} -q net.wlan.devices`; do
515 child_wlans=`get_if_var $parent wlans_IF`
516 for child in ${child_wlans}; do
517 if ! ifexists $child; then
518 continue
519 fi
520
521 ifconfig -n $child destroy
522 if [ $? -eq 0 ]; then
523 _list="${_list}${_prefix}${child}"
524 [ -z "$_prefix" ] && _prefix=' '
525 fi
526 done
527 done
528
529 if [ -n "${_list}" ]; then
530 echo "Destroyed wlan interfaces: ${_list}"
531 fi
532 debug "Destroyed wlan interfaces: ${_list}"
533}
534
e4b0f1d1
AL
535# clone_up
536# Create cloneable interfaces.
9c600e7d
MD
537#
538clone_up()
539{
e4b0f1d1 540 local _prefix _list ifn
9c600e7d
MD
541 _prefix=
542 _list=
e4b0f1d1 543
9c600e7d
MD
544 for ifn in ${cloned_interfaces}; do
545 ifconfig ${ifn} create
546 if [ $? -eq 0 ]; then
547 _list="${_list}${_prefix}${ifn}"
548 [ -z "$_prefix" ] && _prefix=' '
549 fi
550 done
e4b0f1d1
AL
551 if [ -n "${_list}" ]; then
552 echo "Created clone interfaces: ${_list}"
553 fi
554 debug "Created clone interfaces: ${_list}"
9c600e7d
MD
555}
556
e4b0f1d1
AL
557# clone_down
558# Destroy cloned interfaces.
9c600e7d
MD
559#
560clone_down()
561{
e4b0f1d1 562 local _prefix _list ifn
9c600e7d
MD
563 _prefix=
564 _list=
e4b0f1d1 565
9c600e7d
MD
566 for ifn in ${cloned_interfaces}; do
567 ifconfig ${ifn} destroy
568 if [ $? -eq 0 ]; then
569 _list="${_list}${_prefix}${ifn}"
570 [ -z "$_prefix" ] && _prefix=' '
571 fi
572 done
e4b0f1d1
AL
573 if [ -n "${_list}" ]; then
574 echo "Destroyed clone interfaces: ${_list}"
575 fi
576 debug "Destroyed clone interfaces: ${_list}"
9c600e7d
MD
577}
578
e4b0f1d1
AL
579# gif_up
580# Create IPv6<-->IPv4 tunnels
581#
9c600e7d 582gif_up() {
e4b0f1d1
AL
583 local _if _peers
584
9c600e7d
MD
585 case ${gif_interfaces} in
586 [Nn][Oo] | '')
e4b0f1d1 587 return
9c600e7d
MD
588 ;;
589 esac
e4b0f1d1
AL
590
591 for _if in ${gif_interfaces}; do
592 eval _peers=\$gifconfig_${_if}
593 case ${_peers} in
594 '')
595 continue
596 ;;
597 *)
598 ifconfig $_if create >/dev/null 2>&1
599 ifconfig $_if tunnel ${_peers}
600 ifconfig $_if up
601 ;;
602 esac
603 done
9c600e7d
MD
604}
605
f26c267a
SW
606# ifnet_rename
607# Rename all requested interfaces.
608#
609ifnet_rename()
610{
e4b0f1d1 611 local _ifn_list _if _ifname
f26c267a 612
e4b0f1d1 613 _ifn_list=$(ifconfig -l)
f26c267a 614 [ -z "$_ifn_list" ] && return 0
e4b0f1d1 615
f26c267a 616 for _if in ${_ifn_list} ; do
a939f930 617 _ifname=`get_if_var $_if ifconfig_IF_name`
e4b0f1d1 618 if [ -n "$_ifname" ]; then
f26c267a
SW
619 ifconfig $_if name $_ifname
620 fi
621 done
622 return 0
623}
624
0e387345
AL
625# list_net_interfaces
626# List all network interfaces.
acba6ed7
SS
627# Note that the list will include cloned interfaces if applicable.
628# Cloned interfaces must already exist to have a chance to appear
629# in the list if ${network_interfaces} is set to `auto'.
9c600e7d
MD
630#
631list_net_interfaces()
632{
0e387345
AL
633 local _tmplist _autolist _lo _if
634
9c600e7d
MD
635 case ${network_interfaces} in
636 [Aa][Uu][Tt][Oo])
3928a593 637 _autolist=$(ifconfig -l)
667713fe
HT
638 _lo=
639 for _if in ${_autolist} ; do
640 if [ "$_if" = "lo0" ]; then
641 _lo="lo0"
642 else
643 _tmplist="${_tmplist} ${_if}"
644 fi
645 done
646 _tmplist="${_lo} ${_tmplist}"
9c600e7d
MD
647 ;;
648 *)
acba6ed7 649 _tmplist="${network_interfaces} ${cloned_interfaces}"
9c600e7d
MD
650 ;;
651 esac
9c600e7d 652
0e387345 653 echo $_tmplist
9c600e7d
MD
654}
655
656hexdigit()
657{
658 if [ $1 -lt 10 ]; then
659 echo $1
660 else
661 case $1 in
662 10) echo a ;;
663 11) echo b ;;
664 12) echo c ;;
665 13) echo d ;;
666 14) echo e ;;
667 15) echo f ;;
668 esac
669 fi
670}
671
672hexprint()
673{
e4b0f1d1 674 local val str dig
9c600e7d
MD
675 val=$1
676 str=''
677
678 dig=`hexdigit $((${val} & 15))`
679 str=${dig}${str}
680 val=$((${val} >> 4))
681 while [ ${val} -gt 0 ]; do
682 dig=`hexdigit $((${val} & 15))`
683 str=${dig}${str}
684 val=$((${val} >> 4))
685 done
686
687 echo ${str}
688}
689
8716355d
DF
690is_wired_interface()
691{
692 local media
693
694 case `ifconfig $1 2>/dev/null` in
695 *media:?Ethernet*) media=Ethernet ;;
696 esac
697
698 test "$media" = "Ethernet"
699}
700
701is_ndis_interface()
702{
703 case `sysctl -n net.wlan.${1#wlan}.%parent 2>/dev/null` in
704 ndis*) true ;;
705 *) false ;;
706 esac
707}
e4b0f1d1
AL
708
709#
710# IPv6-specific setup subroutines
711#
712
9c600e7d
MD
713# Setup the interfaces for IPv6
714network6_interface_setup()
715{
e4b0f1d1
AL
716 local interfaces rtsol_interfaces ipv6_ifconfig
717 local rtsol_available rtsol_interface
3b4e0f2a 718 local prefix laddr hostid address
e4b0f1d1
AL
719 local _if j
720
9c600e7d
MD
721 interfaces=$*
722 rtsol_interfaces=''
723 case ${ipv6_gateway_enable} in
724 [Yy][Ee][Ss])
725 rtsol_available=no
726 ;;
727 *)
728 rtsol_available=yes
729 ;;
730 esac
e4b0f1d1 731 for _if in $interfaces; do
9c600e7d 732 rtsol_interface=yes
e4b0f1d1 733 prefix=`get_if_var $_if ipv6_prefix_IF`
9c600e7d
MD
734 if [ -n "${prefix}" ]; then
735 rtsol_available=no
736 rtsol_interface=no
e4b0f1d1 737 laddr=`network6_getladdr $_if`
9c600e7d
MD
738 hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'`
739 for j in ${prefix}; do
740 address=$j\:${hostid}
e4b0f1d1 741 ifconfig $_if inet6 ${address} prefixlen 64 alias
9c600e7d
MD
742
743 case ${ipv6_gateway_enable} in
744 [Yy][Ee][Ss])
745 # subnet-router anycast address
746 # (rfc2373)
e4b0f1d1 747 ifconfig $_if inet6 $j:: prefixlen 64 \
9c600e7d
MD
748 alias anycast
749 ;;
750 esac
751 done
752 fi
e4b0f1d1 753 ipv6_ifconfig=`ifconfig_getargs $_if ipv6`
203bea78 754 ipv6_ifconfig="${ipv6_ifconfig#inet6 }"
9c600e7d
MD
755 if [ -n "${ipv6_ifconfig}" ]; then
756 rtsol_available=no
757 rtsol_interface=no
e4b0f1d1 758 ifconfig $_if inet6 ${ipv6_ifconfig} alias
9c600e7d
MD
759 fi
760
e4b0f1d1
AL
761 if [ "${rtsol_available}" = "yes" -a \
762 "${rtsol_interface}" = "yes" ]; then
9c600e7d 763 case ${i} in
06937ef9 764 lo0|gif[0-9]*|stf[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*)
9c600e7d
MD
765 ;;
766 *)
e4b0f1d1 767 rtsol_interfaces="${rtsol_interfaces} ${_if}"
9c600e7d
MD
768 ;;
769 esac
770 else
e4b0f1d1 771 ifconfig $_if inet6
9c600e7d
MD
772 fi
773 done
774
e4b0f1d1 775 if [ "${rtsol_available}" = "yes" -a -n "${rtsol_interfaces}" ]; then
9c600e7d
MD
776 # Act as endhost - automatically configured.
777 # You can configure only single interface, as
778 # specification assumes that autoconfigured host has
779 # single interface only.
b0a4258d 780 ${SYSCTL_W} net.inet6.ip6.accept_rtadv=1
9c600e7d
MD
781 set ${rtsol_interfaces}
782 ifconfig $1 up
e4b0f1d1 783 echo "Auto configuring interface $1 ..."
9c600e7d
MD
784 rtsol $1
785 fi
786
e4b0f1d1 787 for _if in $interfaces; do
3b4e0f2a 788 ifalias_up $_if ipv6
9c600e7d
MD
789 done
790}
791
792# Setup IPv6 to IPv4 mapping
793network6_stf_setup()
794{
e4b0f1d1
AL
795 local stf_prefixlen stf_interface_ipv6_ifid
796 local hexfrag1 hexfrag2 ipv4_in_hexformat laddr
797 local _if OIFS
798
9c600e7d
MD
799 case ${stf_interface_ipv4addr} in
800 [Nn][Oo] | '')
801 ;;
802 *)
803 # assign IPv6 addr and interface route for 6to4 interface
804 stf_prefixlen=$((16+${stf_interface_ipv4plen:-0}))
805 OIFS="$IFS"
806 IFS=".$IFS"
807 set ${stf_interface_ipv4addr}
808 IFS="$OIFS"
809 hexfrag1=`hexprint $(($1*256 + $2))`
810 hexfrag2=`hexprint $(($3*256 + $4))`
811 ipv4_in_hexformat="${hexfrag1}:${hexfrag2}"
812 case ${stf_interface_ipv6_ifid} in
813 [Aa][Uu][Tt][Oo] | '')
e4b0f1d1
AL
814 for _if in ${ipv6_network_interfaces}; do
815 laddr=`network6_getladdr $_if`
9c600e7d
MD
816 case ${laddr} in
817 '')
818 ;;
819 *)
820 break
821 ;;
822 esac
823 done
824 stf_interface_ipv6_ifid=`expr "${laddr}" : \
825 'fe80::\(.*\)%\(.*\)'`
826 case ${stf_interface_ipv6_ifid} in
827 '')
828 stf_interface_ipv6_ifid=0:0:0:1
829 ;;
830 esac
831 ;;
832 esac
833 ifconfig stf0 create >/dev/null 2>&1
834 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \
835 prefixlen ${stf_prefixlen}
836 # disallow packets to malicious 6to4 prefix
837 route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject
838 route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject
839 route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject
840 route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject
841 ;;
842 esac
843}
844
845# Setup static routes
846network6_static_routes_setup()
847{
e4b0f1d1
AL
848 local _rt
849
9c600e7d
MD
850 # Set up any static routes.
851 case ${ipv6_defaultrouter} in
852 [Nn][Oo] | '')
853 ;;
854 *)
855 ipv6_static_routes="default ${ipv6_static_routes}"
856 ipv6_route_default="default ${ipv6_defaultrouter}"
857 ;;
858 esac
859 case ${ipv6_static_routes} in
860 [Nn][Oo] | '')
861 ;;
862 *)
e4b0f1d1
AL
863 for _rt in ${ipv6_static_routes}; do
864 eval ipv6_route_args=\$ipv6_route_${_rt}
9c600e7d
MD
865 route add -inet6 ${ipv6_route_args}
866 done
867 ;;
868 esac
869}
870
9c600e7d
MD
871# Install the "default interface" to kernel, which will be used
872# as the default route when there's no router.
873network6_default_interface_setup()
874{
e4b0f1d1
AL
875 local _if laddr
876
9c600e7d
MD
877 # Choose IPv6 default interface if it is not clearly specified.
878 case ${ipv6_default_interface} in
879 '')
e4b0f1d1
AL
880 for _if in ${ipv6_network_interfaces}; do
881 if [ "${_if}" = "lo0" ]; then
9c600e7d 882 continue
e4b0f1d1
AL
883 fi
884
885 laddr=`network6_getladdr $_if exclude_tentative`
9c600e7d
MD
886 case ${laddr} in
887 '')
888 ;;
889 *)
e4b0f1d1 890 ipv6_default_interface=$_if
9c600e7d
MD
891 break
892 ;;
893 esac
894 done
895 ;;
896 esac
897
898 # Disallow unicast packets without outgoing scope identifiers,
899 # or route such packets to a "default" interface, if it is specified.
900 route add -inet6 fe80:: -prefixlen 10 ::1 -reject
901 case ${ipv6_default_interface} in
902 [Nn][Oo] | '')
903 route add -inet6 ff02:: -prefixlen 16 ::1 -reject
904 ;;
905 *)
906 laddr=`network6_getladdr ${ipv6_default_interface}`
907 route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \
908 -cloning
909
910 # Disable installing the default interface with the
911 # case net.inet6.ip6.forwarding=0 and
912 # net.inet6.ip6.accept_rtadv=0, due to avoid conflict
913 # between the default router list and the manual
914 # configured default route.
915 case ${ipv6_gateway_enable} in
916 [Yy][Ee][Ss])
917 ;;
918 *)
b0a4258d 919 if [ `${SYSCTL_N} net.inet6.ip6.accept_rtadv` -eq 1 ]
9c600e7d
MD
920 then
921 ndp -I ${ipv6_default_interface}
922 fi
923 ;;
924 esac
925 ;;
926 esac
927}
928
929network6_getladdr()
930{
e4b0f1d1
AL
931 local proto addr rest
932
9c600e7d
MD
933 ifconfig $1 2>/dev/null | while read proto addr rest; do
934 case ${proto} in
935 inet6)
936 case ${addr} in
937 fe80::*)
938 if [ -z "$2" ]; then
939 echo ${addr}
940 return
941 fi
942 case ${rest} in
943 *tentative*)
944 continue
945 ;;
946 *)
947 echo ${addr}
948 return
949 esac
950 esac
951 esac
952 done
953}