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