]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - etc/network.subr
This commit was generated by cvs2svn to compensate for changes in r158782,
[FreeBSD/FreeBSD.git] / etc / network.subr
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 #
25 # $FreeBSD$
26 #
27
28 #
29 # Subroutines commonly used from network startup scripts.
30 # Requires that rc.conf be loaded first.
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
37 #       had no arguments.  Pseudo arguments DHCP and WPA are handled
38 #       here.
39 #
40 ifconfig_up()
41 {
42         _cfg=1
43
44         ifconfig_args=`ifconfig_getargs $1`
45         if [ -n "${ifconfig_args}" ]; then
46                 ifconfig $1 up
47                 ifconfig $1 ${ifconfig_args}
48                 _cfg=0
49         fi
50
51         if wpaif $1; then
52                 if [ $_cfg -ne 0 ] ; then
53                         ifconfig $1 up
54                 fi
55                 /etc/rc.d/wpa_supplicant start $1
56                 _cfg=0          # XXX: not sure this should count
57         fi
58
59         if dhcpif $1; then
60                 if [ $_cfg -ne 0 ] ; then
61                         ifconfig $1 up
62                 fi
63                 if syncdhcpif $1; then
64                         /etc/rc.d/dhclient start $1
65                 fi
66                 _cfg=0
67         fi
68
69         return $_cfg
70 }
71
72 # ifconfig_down if
73 #       Remove all inet entries from the $if interface. It returns
74 #       0 if inet entries were found and removed. It returns 1 if
75 #       no entries were found or they could not be removed.
76 #
77 #       XXX: should not be only inet
78 #
79 ifconfig_down()
80 {
81         [ -z "$1" ] && return 1
82         _ifs="^"
83         _cfg=1
84
85         inetList="`ifconfig $1 | grep 'inet ' | tr "\n" "$_ifs"`"
86
87         oldifs="$IFS"
88         IFS="$_ifs"
89         for _inet in $inetList ; do
90                 # get rid of extraneous line
91                 [ -z "$_inet" ] && break
92
93                 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'`
94
95                 IFS="$oldifs"
96                 ifconfig $1 ${_inet} delete
97                 IFS="$_ifs"
98                 _cfg=0
99         done
100         IFS="$oldifs"
101
102         if wpaif $1; then
103                 /etc/rc.d/wpa_supplicant stop $1
104                 _cfg=0
105         fi
106
107         if dhcpif $1; then
108                 /etc/rc.d/dhclient stop $1
109                 _cfg=0
110         fi
111
112         ifconfig $1 down
113
114         return $_cfg
115 }
116
117 # get_if_var if var [default]
118 #       Return the value of the pseudo-hash corresponding to $if where
119 #       $var is a string containg the sub-string "IF" which will be
120 #       replaced with $if after the characters defined in _punct are
121 #       replaced with '_'. If the variable is unset, replace it with
122 #       $default if given.
123 get_if_var()
124 {
125         if [ $# -ne 2 -a $# -ne 3 ]; then
126                 err 3 'USAGE: get_if_var name var [default]'
127         fi
128
129         _if=$1
130         _punct=". - / +"
131         for _punct_c in $_punct; do
132                 _if=`ltr ${_if} ${_punct_c} '_'`
133         done
134         _var=$2
135         _default=$3
136
137         prefix=${_var%%IF*}
138         suffix=${_var##*IF}
139         eval echo \${${prefix}${_if}${suffix}-${_default}}
140 }
141
142 # _ifconfig_getargs if
143 #       Echos the arguments for the supplied interface to stdout.
144 #       returns 1 if empty.  In general, ifconfig_getargs should be used
145 #       outside this file.
146 _ifconfig_getargs()
147 {
148         _ifn=$1
149         if [ -z "$_ifn" ]; then
150                 return 1
151         fi
152
153         get_if_var $_ifn ifconfig_IF "$ifconfig_DEFAULT"
154 }
155
156 # ifconfig_getargs if
157 #       Takes the result from _ifconfig_getargs and removes pseudo
158 #       args such as DHCP and WPA.
159 ifconfig_getargs()
160 {
161         _tmpargs=`_ifconfig_getargs $1`
162         if [ $? -eq 1 ]; then
163                 return 1
164         fi
165         _args=
166
167         for _arg in $_tmpargs; do
168                 case $_arg in
169                 [Dd][Hh][Cc][Pp]) ;;
170                 [Nn][Oo][Aa][Uu][Tt][Oo]) ;;
171                 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;;
172                 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;;
173                 [Ww][Pp][Aa]) ;;
174                 *)
175                         _args="$_args $_arg"
176                         ;;
177                 esac
178         done
179
180         echo $_args
181 }
182
183 # autoif
184 #       Returns 0 if the interface should be automaticly configured at
185 #       boot time and 1 otherwise.
186 autoif()
187 {
188         _tmpargs=`_ifconfig_getargs $1`
189         for _arg in $_tmpargs; do
190                 case $_arg in
191                 [Nn][Oo][Aa][Uu][Tt][Oo])
192                         return 1
193                         ;;
194                 esac
195         done
196         return 0
197 }
198
199 # dhcpif if
200 #       Returns 0 if the interface is a DHCP interface and 1 otherwise.
201 dhcpif()
202 {
203         _tmpargs=`_ifconfig_getargs $1`
204         for _arg in $_tmpargs; do
205                 case $_arg in
206                 [Dd][Hh][Cc][Pp])
207                         return 0
208                         ;;
209                 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
210                         return 0
211                         ;;
212                 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
213                         return 0
214                         ;;
215                 esac
216         done
217         return 1
218 }
219
220 # syncdhcpif
221 #       Returns 0 if the interface should be configured synchronously and
222 #       1 otherwise.
223 syncdhcpif()
224 {
225         _tmpargs=`_ifconfig_getargs $1`
226         for _arg in $_tmpargs; do
227                 case $_arg in
228                 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
229                         return 1
230                         ;;
231                 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
232                         return 0
233                         ;;
234                 esac
235         done
236         if checkyesno synchronous_dhclient; then
237                 return 0
238         else
239                 return 1
240         fi
241 }
242
243 # wpaif if
244 #       Returns 0 if the interface is a WPA interface and 1 otherwise.
245 wpaif()
246 {
247         _tmpargs=`_ifconfig_getargs $1`
248         for _arg in $_tmpargs; do
249                 case $_arg in
250                 [Ww][Pp][Aa])
251                         return 0
252                         ;;
253                 esac
254         done
255         return 1
256 }
257
258 # ipv4_up if
259 #  add IPv4 addresses to the interface $if 
260 ipv4_up()
261 {
262         _if=$1
263         ifalias_up ${_if}
264         ipv4_addrs_common ${_if} alias
265 }
266
267 # ipv4_down if
268 #  remove IPv4 addresses from the interface $if
269 ipv4_down()
270 {
271         _if=$1
272         ifalias_down ${_if}
273         ipv4_addrs_common ${_if} -alias
274 }
275
276 # ipv4_addrs_common if action
277 #   Evaluate the ifconfig_if_ipv4 arguments for interface $if
278 #   and use $action to add or remove IPv4 addresses from $if.
279 ipv4_addrs_common()
280 {  
281         _ret=1
282         _if=$1
283         _action=$2
284     
285         # get ipv4-addresses
286         cidr_addr=`get_if_var $_if ipv4_addrs_IF`
287     
288         for _cidr in ${cidr_addr}; do
289                 _ipaddr=${_cidr%%/*}
290                 _netmask="/"${_cidr##*/}
291                 _range=${_ipaddr##*.}
292                 _ipnet=${_ipaddr%.*}
293                 _iplow=${_range%-*}
294                 _iphigh=${_range#*-}
295
296                 # clear netmask when removing aliases
297                 if [ "${_action}" = "-alias" ]; then
298                         _netmask=""
299                 fi
300         
301                 _ipcount=${_iplow}
302                 while [ "${_ipcount}" -le "${_iphigh}" ]; do
303                         eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}"
304                         _ipcount=$((${_ipcount}+1))
305                         _ret=0
306
307                         # only the first ipaddr in a subnet need the real netmask
308                         if [ "${_action}" != "-alias" ]; then
309                                 _netmask="/32"
310                         fi
311                 done
312         done
313         return $_ret
314 }
315
316 # ifalias_up if
317 #       Configure aliases for network interface $if.
318 #       It returns 0 if at least one alias was configured or
319 #       1 if there were none.
320 #
321 ifalias_up()
322 {
323         _ret=1
324         alias=0
325         while : ; do
326                 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
327                 if [ -n "${ifconfig_args}" ]; then
328                         ifconfig $1 ${ifconfig_args} alias
329                         alias=$((${alias} + 1))
330                         _ret=0
331                 else
332                         break
333                 fi
334         done
335         return $_ret
336 }
337
338 #ifalias_down if
339 #       Remove aliases for network interface $if.
340 #       It returns 0 if at least one alias was removed or
341 #       1 if there were none.
342 #
343 ifalias_down()
344 {
345         _ret=1
346         alias=0
347         while : ; do
348                 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
349                 if [ -n "${ifconfig_args}" ]; then
350                         ifconfig $1 ${ifconfig_args} -alias
351                         alias=$((${alias} + 1))
352                         _ret=0
353                 else
354                         break
355                 fi
356         done
357         return $_ret
358 }
359
360 # ifscript_up if
361 #       Evaluate a startup script for the $if interface.
362 #       It returns 0 if a script was found and processed or
363 #       1 if no script was found.
364 #
365 ifscript_up()
366 {
367         if [ -r /etc/start_if.$1 ]; then
368                 . /etc/start_if.$1
369                 return 0
370         fi
371         return 1
372 }
373
374 # ifscript_down if
375 #       Evaluate a shutdown script for the $if interface.
376 #       It returns 0 if a script was found and processed or
377 #       1 if no script was found.
378 #
379 ifscript_down()
380 {
381         if [ -r /etc/stop_if.$1 ]; then
382                 . /etc/stop_if.$1
383                 return 0
384         fi
385         return 1
386 }
387
388 # Create cloneable interfaces.
389 #
390 clone_up()
391 {
392         _prefix=
393         _list=
394         for ifn in ${cloned_interfaces}; do
395                 ifconfig ${ifn} create
396                 if [ $? -eq 0 ]; then
397                         _list="${_list}${_prefix}${ifn}"
398                         [ -z "$_prefix" ] && _prefix=' '
399                 fi
400         done
401         debug "Cloned: ${_list}"
402 }
403
404 # Destroy cloned interfaces. Destroyed interfaces are echoed
405 # to standard output.
406 #
407 clone_down()
408 {
409         _prefix=
410         _list=
411         for ifn in ${cloned_interfaces}; do
412                 ifconfig ${ifn} destroy
413                 if [ $? -eq 0 ]; then
414                         _list="${_list}${_prefix}${ifn}"
415                         [ -z "$_prefix" ] && _prefix=' '
416                 fi
417         done
418         debug "Destroyed clones: ${_list}"
419 }
420
421 gif_up() {
422         case ${gif_interfaces} in
423         [Nn][Oo] | '')
424                 ;;
425         *)
426                 for i in ${gif_interfaces}; do
427                         peers=`get_if_var $i gifconfig_IF`
428                         case ${peers} in
429                         '')
430                                 continue
431                                 ;;
432                         *)
433                                 ifconfig $i create >/dev/null 2>&1
434                                 ifconfig $i tunnel ${peers}
435                                 ifconfig $i up
436                                 ;;
437                         esac
438                 done
439                 ;;
440         esac
441 }
442
443 #
444 # ipx_up ifn
445 # Configure any IPX addresses for interface $ifn. Returns 0 if IPX
446 # arguments were found and configured; returns 1 otherwise.
447 #
448 ipx_up()
449 {
450         ifn="$1"
451         ifconfig_args=`get_if_var $ifn ifconfig_IF_ipx`
452         if [ -n "${ifconfig_args}" ]; then
453                 ifconfig ${ifn} ${ifconfig_args}
454                 return 0
455         fi
456         return 1
457 }
458
459 # ipx_down ifn
460 #       Remove IPX addresses for interface $ifn. Returns 0 if IPX
461 #       addresses were found and unconfigured. It returns 1, otherwise.
462 #
463 ipx_down()
464 {
465         [ -z "$1" ] && return 1
466         _ifs="^"
467         _ret=1
468
469         ipxList="`ifconfig $1 | grep 'ipx ' | tr "\n" "$_ifs"`"
470
471         oldifs="$IFS"
472         IFS="$_ifs"
473         for _ipx in $ipxList ; do
474                 # get rid of extraneous line
475                 [ -z "$_ipx" ] && break
476
477                 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'`
478
479                 IFS="$oldifs"
480                 ifconfig $1 ${_ipx} delete
481                 IFS="$_ifs"
482                 _ret=0
483         done
484         IFS="$oldifs"
485
486         return $_ret
487 }
488
489 # ifnet_rename
490 #       Rename all requested interfaces.
491 #
492 ifnet_rename()
493 {
494
495         _ifn_list="`ifconfig -l`"
496         [ -z "$_ifn_list" ] && return 0
497         for _if in ${_ifn_list} ; do
498                 _ifname=`get_if_var $_if ifconfig_IF_name`
499                 if [ ! -z "$_ifname" ]; then
500                         ifconfig $_if name $_ifname
501                 fi
502         done
503         return 0
504 }
505
506 #
507 # list_net_interfaces type
508 #       List all network interfaces. The type of interface returned
509 #       can be controlled by the type argument. The type
510 #       argument can be any of the following:
511 #               nodhcp - all interfaces, excluding DHCP configured interfaces
512 #               dhcp   - list only DHCP configured interfaces
513 #       If no argument is specified all network interfaces are output.
514 #       Note that the list will include cloned interfaces if applicable.
515 #       Cloned interfaces must already exist to have a chance to appear
516 #       in the list if ${network_interfaces} is set to `auto'.
517 #
518 list_net_interfaces()
519 {
520         type=$1
521
522         # Get a list of ALL the interfaces and make lo0 first if it's there.
523         #
524         case ${network_interfaces} in
525         [Aa][Uu][Tt][Oo])
526                 _prefix=''
527                 _autolist="`ifconfig -l`"
528                 _lo=
529                 for _if in ${_autolist} ; do
530                         if autoif $_if; then
531                                 if [ "$_if" = "lo0" ]; then
532                                         _lo="lo0 "
533                                 else
534                                         _tmplist="${_tmplist}${_prefix}${_if}"
535                                         [ -z "$_prefix" ] && _prefix=' '
536                                 fi
537                         fi
538                 done
539                 _tmplist="${_lo}${_tmplist}"
540                 ;;
541         *)
542                 _tmplist="${network_interfaces} ${cloned_interfaces}"
543                 ;;
544         esac
545
546         if [ -z "$type" ]; then
547                 echo $_tmplist
548                 return 0
549         fi
550
551         # Separate out dhcp and non-dhcp interfaces
552         #
553         _aprefix=
554         _bprefix=
555         for _if in ${_tmplist} ; do
556                 if dhcpif $_if; then
557                         _dhcplist="${_dhcplist}${_aprefix}${_if}"
558                         [ -z "$_aprefix" ] && _aprefix=' '
559                 elif [ -n "`_ifconfig_getargs $_if`" ]; then
560                         _nodhcplist="${_nodhcplist}${_bprefix}${_if}"
561                         [ -z "$_bprefix" ] && _bprefix=' '
562                 fi
563         done
564
565         case "$type" in
566         nodhcp)
567                 echo $_nodhcplist
568                 ;;
569         dhcp)
570                 echo $_dhcplist
571                 ;;
572         esac
573         return 0
574 }
575
576 hexdigit()
577 {
578         if [ $1 -lt 10 ]; then
579                 echo $1
580         else
581                 case $1 in
582                 10)     echo a ;;
583                 11)     echo b ;;
584                 12)     echo c ;;
585                 13)     echo d ;;
586                 14)     echo e ;;
587                 15)     echo f ;;
588                 esac
589         fi
590 }
591
592 hexprint()
593 {
594         val=$1
595         str=''
596
597         dig=`hexdigit $((${val} & 15))`
598         str=${dig}${str}
599         val=$((${val} >> 4))
600         while [ ${val} -gt 0 ]; do
601                 dig=`hexdigit $((${val} & 15))`
602                 str=${dig}${str}
603                 val=$((${val} >> 4))
604         done
605
606         echo ${str}
607 }
608
609 # Setup the interfaces for IPv6
610 network6_interface_setup()
611 {
612         interfaces=$*
613         rtsol_interfaces=''
614         case ${ipv6_gateway_enable} in
615         [Yy][Ee][Ss])
616                 rtsol_available=no
617                 ;;
618         *)
619                 rtsol_available=yes
620                 ;;
621         esac
622         for i in $interfaces; do
623                 rtsol_interface=yes
624                 prefix=`get_if_var $i ipv6_prefix_IF`
625                 if [ -n "${prefix}" ]; then
626                         rtsol_available=no
627                         rtsol_interface=no
628                         laddr=`network6_getladdr $i`
629                         hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'`
630                         for j in ${prefix}; do
631                                 address=$j\:${hostid}
632                                 ifconfig $i inet6 ${address} prefixlen 64 alias
633
634                                 case ${ipv6_gateway_enable} in
635                                 [Yy][Ee][Ss])
636                                         # subnet-router anycast address
637                                         # (rfc2373)
638                                         ifconfig $i inet6 $j:: prefixlen 64 \
639                                                 alias anycast
640                                         ;;
641                                 esac
642                         done
643                 fi
644                 ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF`
645                 if [ -n "${ipv6_ifconfig}" ]; then
646                         rtsol_available=no
647                         rtsol_interface=no
648                         ifconfig $i inet6 ${ipv6_ifconfig} alias
649                 fi
650
651                 if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ]
652                 then
653                         case ${i} in
654                         lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*)
655                                 ;;
656                         *)
657                                 rtsol_interfaces="${rtsol_interfaces} ${i}"
658                                 ;;
659                         esac
660                 else
661                         ifconfig $i inet6
662                 fi
663         done
664
665         if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then
666                 # Act as endhost - automatically configured.
667                 # You can configure only single interface, as
668                 # specification assumes that autoconfigured host has
669                 # single interface only.
670                 sysctl net.inet6.ip6.accept_rtadv=1
671                 set ${rtsol_interfaces}
672                 ifconfig $1 up
673                 rtsol ${rtsol_flags} $1
674         fi
675
676         for i in $interfaces; do
677                 alias=0
678                 while : ; do
679                         ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF_alias${alias}`
680                         if [ -z "${ipv6_ifconfig}" ]; then
681                                 break;
682                         fi
683                         ifconfig $i inet6 ${ipv6_ifconfig} alias
684                         alias=$((${alias} + 1))
685                 done
686         done
687 }
688
689 # Setup IPv6 to IPv4 mapping
690 network6_stf_setup()
691 {
692         case ${stf_interface_ipv4addr} in
693         [Nn][Oo] | '')
694                 ;;
695         *)
696                 # assign IPv6 addr and interface route for 6to4 interface
697                 stf_prefixlen=$((16+${stf_interface_ipv4plen:-0}))
698                 OIFS="$IFS"
699                 IFS=".$IFS"
700                 set ${stf_interface_ipv4addr}
701                 IFS="$OIFS"
702                 hexfrag1=`hexprint $(($1*256 + $2))`
703                 hexfrag2=`hexprint $(($3*256 + $4))`
704                 ipv4_in_hexformat="${hexfrag1}:${hexfrag2}"
705                 case ${stf_interface_ipv6_ifid} in
706                 [Aa][Uu][Tt][Oo] | '')
707                         for i in ${ipv6_network_interfaces}; do
708                                 laddr=`network6_getladdr ${i}`
709                                 case ${laddr} in
710                                 '')
711                                         ;;
712                                 *)
713                                         break
714                                         ;;
715                                 esac
716                         done
717                         stf_interface_ipv6_ifid=`expr "${laddr}" : \
718                                                       'fe80::\(.*\)%\(.*\)'`
719                         case ${stf_interface_ipv6_ifid} in
720                         '')
721                                 stf_interface_ipv6_ifid=0:0:0:1
722                                 ;;
723                         esac
724                         ;;
725                 esac
726                 ifconfig stf0 create >/dev/null 2>&1
727                 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \
728                         prefixlen ${stf_prefixlen}
729                 # disallow packets to malicious 6to4 prefix
730                 route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject
731                 route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject
732                 route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject
733                 route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject
734                 ;;
735         esac
736 }
737
738 # Setup static routes
739 network6_static_routes_setup()
740 {
741         # Set up any static routes.
742         case ${ipv6_defaultrouter} in
743         [Nn][Oo] | '')
744                 ;;
745         *)
746                 ipv6_static_routes="default ${ipv6_static_routes}"
747                 ipv6_route_default="default ${ipv6_defaultrouter}"
748                 ;;
749         esac
750         case ${ipv6_static_routes} in
751         [Nn][Oo] | '')
752                 ;;
753         *)
754                 for i in ${ipv6_static_routes}; do
755                         ipv6_route_args=`get_if_var $i ipv6_route_IF`
756                         route add -inet6 ${ipv6_route_args}
757                 done
758                 ;;
759         esac
760 }
761
762 # Setup faith
763 network6_faith_setup()
764 {
765         case ${ipv6_faith_prefix} in
766         [Nn][Oo] | '')
767                 ;;
768         *)
769                 sysctl net.inet6.ip6.keepfaith=1
770                 ifconfig faith0 create >/dev/null 2>&1
771                 ifconfig faith0 up
772                 for prefix in ${ipv6_faith_prefix}; do
773                         prefixlen=`expr "${prefix}" : ".*/\(.*\)"`
774                         case ${prefixlen} in
775                         '')
776                                 prefixlen=96
777                                 ;;
778                         *)
779                                 prefix=`expr "${prefix}" : \
780                                              "\(.*\)/${prefixlen}"`
781                                 ;;
782                         esac
783                         route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1
784                         route change -inet6 ${prefix} -prefixlen ${prefixlen} \
785                                 -ifp faith0
786                 done
787                 ;;
788         esac
789 }
790
791 # Install the "default interface" to kernel, which will be used
792 # as the default route when there's no router.
793 network6_default_interface_setup()
794 {
795         # Choose IPv6 default interface if it is not clearly specified.
796         case ${ipv6_default_interface} in
797         '')
798                 for i in ${ipv6_network_interfaces}; do
799                         case $i in
800                         lo0|faith[0-9]*)
801                                 continue
802                                 ;;
803                         esac
804                         laddr=`network6_getladdr $i exclude_tentative`
805                         case ${laddr} in
806                         '')
807                                 ;;
808                         *)
809                                 ipv6_default_interface=$i
810                                 break
811                                 ;;
812                         esac
813                 done
814                 ;;
815         esac
816
817         # Disallow unicast packets without outgoing scope identifiers,
818         # or route such packets to a "default" interface, if it is specified.
819         route add -inet6 fe80:: -prefixlen 10 ::1 -reject
820         case ${ipv6_default_interface} in
821         [Nn][Oo] | '')
822                 route add -inet6 ff02:: -prefixlen 16 ::1 -reject
823                 ;;
824         *)
825                 laddr=`network6_getladdr ${ipv6_default_interface}`
826                 route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \
827                         -cloning
828
829                 # Disable installing the default interface with the
830                 # case net.inet6.ip6.forwarding=0 and
831                 # net.inet6.ip6.accept_rtadv=0, due to avoid conflict
832                 # between the default router list and the manual
833                 # configured default route.
834                 case ${ipv6_gateway_enable} in
835                 [Yy][Ee][Ss])
836                         ;;
837                 *)
838                         if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ]
839                         then
840                                 ndp -I ${ipv6_default_interface}
841                         fi
842                         ;;
843                 esac
844                 ;;
845         esac
846 }
847
848 network6_getladdr()
849 {
850         ifconfig $1 2>/dev/null | while read proto addr rest; do
851                 case ${proto} in
852                 inet6)
853                         case ${addr} in
854                         fe80::*)
855                                 if [ -z "$2" ]; then
856                                         echo ${addr}
857                                         return
858                                 fi
859                                 case ${rest} in
860                                 *tentative*)
861                                         continue
862                                         ;;
863                                 *)
864                                         echo ${addr}
865                                         return
866                                 esac
867                         esac
868                 esac
869         done
870 }