Initial import from FreeBSD RELENG_4:
[dragonfly.git] / etc / rc.network6
1 #! /bin/sh
2 #
3 # Copyright (c) 2000  The KAME Project
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 #    notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 #    notice, this list of conditions and the following disclaimer in the
13 #    documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 # SUCH DAMAGE.
26 #
27 # $FreeBSD: src/etc/rc.network6,v 1.5.2.23 2002/07/24 18:25:42 ume Exp $
28 #
29
30 # Note that almost all of the user-configurable behavior is not in this
31 # file, but rather in /etc/defaults/rc.conf.  Please check that file
32 # first before contemplating any changes here.  If you do need to change
33 # this file for some reason, we would like to know about it.
34
35 # IPv6 startup
36
37 network6_pass1() {
38         echo -n 'Doing IPv6 network setup:'
39
40         # Initialize IP filtering using ip6fw
41         #
42         if /sbin/ip6fw -q flush > /dev/null 2>&1; then
43                 ipv6_firewall_in_kernel=1
44         else
45                 ipv6_firewall_in_kernel=0
46         fi
47
48         case ${ipv6_firewall_enable} in
49         [Yy][Ee][Ss])
50                 if [ "${ipv6_firewall_in_kernel}" -eq 0 ] && kldload ip6fw; then
51                         ipv6_firewall_in_kernel=1
52                         echo "Kernel IPv6 firewall module loaded."
53                 elif [ "${ipv6_firewall_in_kernel}" -eq 0 ]; then
54                         echo "Warning: IPv6 firewall kernel module failed to load."
55                 fi
56                 ;;
57         esac
58
59         # Load the filters if required
60         #
61         case ${ipv6_firewall_in_kernel} in
62         1)
63                 if [ -z "${ipv6_firewall_script}" ]; then
64                         ipv6_firewall_script=/etc/rc.firewall6
65                 fi
66
67                 case ${ipv6_firewall_enable} in
68                 [Yy][Ee][Ss])
69                         if [ -r "${ipv6_firewall_script}" ]; then
70                                 . "${ipv6_firewall_script}"
71                                 echo -n 'IPv6 Firewall rules loaded.'
72                         elif [ "`ip6fw l 65535`" = "65535 deny ipv6 from any to any" ]; then
73                                 echo -n "Warning: kernel has IPv6 firewall functionality, "
74                                 echo "but IPv6 firewall rules are not enabled."
75                                 echo "           All ipv6 services are disabled."
76                         fi
77
78                         case ${ipv6_firewall_logging} in
79                         [Yy][Ee][Ss] | '')
80                                 echo 'IPv6 Firewall logging=YES'
81                                 sysctl net.inet6.ip6.fw.verbose=1 >/dev/null
82                                 ;;
83                         *)
84                                 ;;
85                         esac
86
87                         ;;
88                 esac
89                 ;;
90         esac
91
92         case ${ipv6_network_interfaces} in
93         [Aa][Uu][Tt][Oo])
94                 #
95                 # list of interfaces, and prefix for interfaces
96                 #
97                 ipv6_network_interfaces="`ifconfig -l`"
98                 ;;
99         [Nn][Oo][Nn][Ee])
100                 ipv6_network_interfaces=''
101                 ;;
102         esac
103
104         # just to make sure
105         ifconfig lo0 up
106
107         # disallow "internal" addresses to appear on the wire
108         route add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject
109         route add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject
110
111         case ${ipv6_gateway_enable} in
112         [Yy][Ee][Ss])
113                 # act as a router
114                 sysctl net.inet6.ip6.forwarding=1
115                 sysctl net.inet6.ip6.accept_rtadv=0
116
117                 # wait for DAD
118                 for i in $ipv6_network_interfaces; do
119                         ifconfig $i up
120                 done
121                 sleep `sysctl -n net.inet6.ip6.dad_count`
122                 sleep 1
123                 ;;
124         *)
125                 # act as endhost - start with manual configuration
126                 # Setup of net.inet6.ip6.accept_rtadv is done later by
127                 # network6_interface_setup.
128                 sysctl net.inet6.ip6.forwarding=0
129                 ;;
130         esac
131
132         if [ -n "${ipv6_network_interfaces}" ]; then
133                 # setting up interfaces
134                 network6_interface_setup $ipv6_network_interfaces
135
136                 # wait for DAD's completion (for global addrs)
137                 sleep `sysctl -n net.inet6.ip6.dad_count`
138                 sleep 1
139         fi
140
141         case ${ipv6_gateway_enable} in
142         [Yy][Ee][Ss])
143                 # Filter out interfaces on which IPv6 addr init failed.
144                 ipv6_working_interfaces=""
145                 for i in ${ipv6_network_interfaces}; do
146                         laddr=`network6_getladdr $i exclude_tentative`
147                         case ${laddr} in
148                         '')
149                                 ;;
150                         *)
151                                 ipv6_working_interfaces="$i \
152                                         ${ipv6_working_interfaces}"
153                                 ;;
154                         esac
155                 done
156                 ipv6_network_interfaces=${ipv6_working_interfaces}
157                 ;;
158         esac
159
160         # 6to4 setup
161         network6_stf_setup
162
163         # install the "default interface" to kernel, which will be used
164         # as the default route when there's no router.
165         network6_default_interface_setup
166
167         # setup static routes
168         network6_static_routes_setup
169
170         # setup faith
171         network6_faith_setup
172
173         # ipv6_router
174         case ${ipv6_router_enable} in
175         [Yy][Ee][Ss])
176                 if [ -x ${ipv6_router} ]; then
177                         echo -n " ${ipv6_router}"
178                         ${ipv6_router} ${ipv6_router_flags}
179                 fi
180                 ;;
181         esac
182
183
184         case ${ipv6_gateway_enable} in
185         [Yy][Ee][Ss])
186                 # rtadvd
187                 # This should enabled with a great care.
188                 # You may want to fine-tune /etc/rtadvd.conf.
189                 #
190                 # And if you wish your rtadvd to receive and process
191                 # router renumbering messages, specify your Router Renumbering
192                 # security policy by -R option.
193                 #
194                 # See `man 3 ipsec_set_policy` for IPsec policy specification
195                 # details.
196                 # (CAUTION: This enables your routers prefix renumbering
197                 # from another machine, so if you enable this, do it with
198                 # enough care.)
199                 #
200                 case ${rtadvd_enable} in
201                 [Yy][Ee][Ss])
202                         # default
203                         case ${rtadvd_interfaces} in
204                         '')
205                                 for i in ${ipv6_network_interfaces}; do
206                                         case $i in
207                                         lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*)
208                                                 continue
209                                                 ;;
210                                         *)
211                                                 rtadvd_interfaces="${rtadvd_interfaces} ${i}"
212                                                 ;;
213                                         esac
214                                 done
215                                 ;;
216                         esac
217                         rtadvd ${rtadvd_interfaces}
218                         #
219                         # Enable Router Renumbering, unicast case
220                         # (use correct src/dst addr)
221                         # rtadvd -R "in ipsec ah/transport/fec0:0:0:1::1-fec0:0:0:10::1/require" \
222                         #       ${ipv6_network_interfaces}
223                         # Enable Router Renumbering, multicast case
224                         # (use correct src addr)
225                         # rtadvd -R "in ipsec ah/transport/ff05::2-fec0:0:0:10::1/require" \
226                         #       ${ipv6_network_interfaces}
227                         ;;
228                 esac
229
230                 # mroute6d
231                 case ${mroute6d_enable} in
232                 [Yy][Ee][Ss])
233                         if [ -x ${mroute6d_program} ]; then
234                                 echo -n " ${mroute6d_program}"
235                                 ${mroute6d_program} ${mroute6d_flags}
236                         fi
237                         ;;
238                 esac
239                 ;;
240         esac
241
242         case ${ipv6_ipv4mapping} in
243         [Yy][Ee][Ss])
244                 echo -n ' IPv4 mapped IPv6 address support=YES'
245                 sysctl net.inet6.ip6.v6only=0 >/dev/null
246                 ;;
247         '' | *)
248                 echo -n ' IPv4 mapped IPv6 address support=NO'
249                 sysctl net.inet6.ip6.v6only=1 >/dev/null
250                 ;;
251         esac
252
253         echo '.'
254
255         # Let future generations know we made it.
256         #
257         network6_pass1_done=YES
258 }
259
260 network6_interface_setup() {
261         interfaces=$*
262         rtsol_interfaces=''
263         case ${ipv6_gateway_enable} in
264         [Yy][Ee][Ss])
265                 rtsol_available=no
266                 ;;
267         *)
268                 rtsol_available=yes
269                 ;;
270         esac
271         for i in $interfaces; do
272                 rtsol_interface=yes
273                 eval prefix=\$ipv6_prefix_$i
274                 if [ -n "${prefix}" ]; then
275                         rtsol_available=no
276                         rtsol_interface=no
277                         laddr=`network6_getladdr $i`
278                         hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'`
279                         for j in ${prefix}; do
280                                 address=$j\:${hostid}
281                                 ifconfig $i inet6 ${address} prefixlen 64 alias
282
283                                 case ${ipv6_gateway_enable} in
284                                 [Yy][Ee][Ss])
285                                         # subnet-router anycast address
286                                         # (rfc2373)
287                                         ifconfig $i inet6 $j:: prefixlen 64 \
288                                                 alias anycast
289                                         ;;
290                                 esac
291                         done
292                 fi
293                 eval ipv6_ifconfig=\$ipv6_ifconfig_$i
294                 if [ -n "${ipv6_ifconfig}" ]; then
295                         rtsol_available=no
296                         rtsol_interface=no
297                         ifconfig $i inet6 ${ipv6_ifconfig} alias
298                 fi
299
300                 if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ]
301                 then
302                         case ${i} in
303                         lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*)
304                                 ;;
305                         *)
306                                 rtsol_interfaces="${rtsol_interfaces} ${i}"
307                                 ;;
308                         esac
309                 else
310                         ifconfig $i inet6
311                 fi
312         done
313
314         if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then
315                 # Act as endhost - automatically configured.
316                 # You can configure only single interface, as
317                 # specification assumes that autoconfigured host has
318                 # single interface only.
319                 sysctl net.inet6.ip6.accept_rtadv=1
320                 set ${rtsol_interfaces}
321                 ifconfig $1 up
322                 rtsol $1
323         fi
324
325         for i in $interfaces; do
326                 alias=0
327                 while : ; do
328                         eval ipv6_ifconfig=\$ipv6_ifconfig_${i}_alias${alias}
329                         if [ -z "${ipv6_ifconfig}" ]; then
330                                 break;
331                         fi
332                         ifconfig $i inet6 ${ipv6_ifconfig} alias
333                         alias=$((${alias} + 1))
334                 done
335         done
336 }
337
338 network6_stf_setup() {
339         case ${stf_interface_ipv4addr} in
340         [Nn][Oo] | '')
341                 ;;
342         *)
343                 # assign IPv6 addr and interface route for 6to4 interface
344                 stf_prefixlen=$((16+${stf_interface_ipv4plen:-0}))
345                 OIFS="$IFS"
346                 IFS=".$IFS"
347                 set ${stf_interface_ipv4addr}
348                 IFS="$OIFS"
349                 ipv4_in_hexformat=`printf "%x:%x\n" \
350                         $(($1*256 + $2)) $(($3*256 + $4))`
351                 case ${stf_interface_ipv6_ifid} in
352                 [Aa][Uu][Tt][Oo] | '')
353                         for i in ${ipv6_network_interfaces}; do
354                                 laddr=`network6_getladdr ${i}`
355                                 case ${laddr} in
356                                 '')
357                                         ;;
358                                 *)
359                                         break
360                                         ;;
361                                 esac
362                         done
363                         stf_interface_ipv6_ifid=`expr "${laddr}" : \
364                                                       'fe80::\(.*\)%\(.*\)'`
365                         case ${stf_interface_ipv6_ifid} in
366                         '')
367                                 stf_interface_ipv6_ifid=0:0:0:1
368                                 ;;
369                         esac
370                         ;;
371                 esac
372                 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \
373                         prefixlen ${stf_prefixlen}
374                 # disallow packets to malicious 6to4 prefix
375                 route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject
376                 route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject
377                 route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject
378                 route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject
379                 ;;
380         esac
381 }
382
383 network6_static_routes_setup() {
384         # Set up any static routes.
385         case ${ipv6_defaultrouter} in
386         [Nn][Oo] | '')
387                 ;;
388         *)
389                 ipv6_static_routes="default ${ipv6_static_routes}"
390                 ipv6_route_default="default ${ipv6_defaultrouter}"
391                 ;;
392         esac
393         case ${ipv6_static_routes} in
394         [Nn][Oo] | '')
395                 ;;
396         *)
397                 for i in ${ipv6_static_routes}; do
398                         eval ipv6_route_args=\$ipv6_route_${i}
399                         route add -inet6 ${ipv6_route_args}
400                 done
401                 ;;
402         esac
403 }
404
405 network6_faith_setup() {
406         case ${ipv6_faith_prefix} in
407         [Nn][Oo] | '')
408                 ;;
409         *)
410                 sysctl net.inet6.ip6.keepfaith=1
411                 ifconfig faith0 create >/dev/null 2>&1
412                 ifconfig faith0 up
413                 for prefix in ${ipv6_faith_prefix}; do
414                         prefixlen=`expr "${prefix}" : ".*/\(.*\)"`
415                         case ${prefixlen} in
416                         '')
417                                 prefixlen=96
418                                 ;;
419                         *)
420                                 prefix=`expr "${prefix}" : \
421                                              "\(.*\)/${prefixlen}"`
422                                 ;;
423                         esac
424                         route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1
425                         route change -inet6 ${prefix} -prefixlen ${prefixlen} \
426                                 -ifp faith0
427                 done
428                 ;;
429         esac
430 }
431
432 network6_default_interface_setup() {
433         # Choose IPv6 default interface if it is not clearly specified.
434         case ${ipv6_default_interface} in
435         '')
436                 for i in ${ipv6_network_interfaces}; do
437                         case $i in
438                         lo0|faith[0-9]*)
439                                 continue
440                                 ;;
441                         esac
442                         laddr=`network6_getladdr $i exclude_tentative`
443                         case ${laddr} in
444                         '')
445                                 ;;
446                         *)
447                                 ipv6_default_interface=$i
448                                 break
449                                 ;;
450                         esac
451                 done
452                 ;;
453         esac
454
455         # Disallow unicast packets without outgoing scope identifiers,
456         # or route such packets to a "default" interface, if it is specified.
457         route add -inet6 fe80:: -prefixlen 10 ::1 -reject
458         case ${ipv6_default_interface} in
459         [Nn][Oo] | '')
460                 route add -inet6 ff02:: -prefixlen 16 ::1 -reject
461                 ;;
462         *)
463                 laddr=`network6_getladdr ${ipv6_default_interface}`
464                 route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \
465                         -cloning
466
467                 # Disable installing the default interface with the
468                 # case net.inet6.ip6.forwarding=0 and
469                 # net.inet6.ip6.accept_rtadv=0, due to avoid conflict
470                 # between the default router list and the manual
471                 # configured default route.
472                 case ${ipv6_gateway_enable} in
473                 [Yy][Ee][Ss])
474                         ;;
475                 *)
476                         if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ]
477                         then
478                                 ndp -I ${ipv6_default_interface}
479                         fi
480                         ;;
481                 esac
482                 ;;
483         esac
484 }
485
486 network6_getladdr() {
487         ifconfig $1 2>/dev/null | while read proto addr rest; do
488                 case ${proto} in
489                 inet6)
490                         case ${addr} in
491                         fe80::*)
492                                 if [ -z "$2" ]; then
493                                         echo ${addr}
494                                         return
495                                 fi
496                                 case ${rest} in
497                                 *tentative*)
498                                         continue
499                                         ;;
500                                 *)
501                                         echo ${addr}
502                                         return
503                                 esac
504                         esac
505                 esac
506         done
507 }