network.subr revision 114942
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: head/etc/network.subr 114942 2003-05-12 11:36:50Z ume $ 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. 38# 39ifconfig_up() 40{ 41 eval ifconfig_args=\$ifconfig_$1 42 if [ -n "${ifconfig_args}" ]; then 43 ifconfig $1 ${ifconfig_args} 44 return 0 45 fi 46 return 1 47} 48 49# ifalias_up if 50# Configure aliases for network interface $if. 51# It returns 0 if at least one alias was configured or 52# 1 if there were none. 53# 54ifalias_up() 55{ 56 _ret=1 57 alias=0 58 while : ; do 59 eval ifconfig_args=\$ifconfig_$1_alias${alias} 60 if [ -n "${ifconfig_args}" ]; then 61 ifconfig $1 ${ifconfig_args} alias 62 alias=$((${alias} + 1)) 63 _ret=0 64 else 65 break 66 fi 67 done 68 return $_ret 69} 70 71# ifscript_up if 72# Evaluate a startup script for the $if interface. 73# It returns 0 if a script was found and processed or 74# 1 if no script was found. 75# 76ifscript_up() 77{ 78 if [ -r /etc/start_if.$1 ]; then 79 . /etc/start_if.$1 80 return 0 81 fi 82 return 1 83} 84 85# Create cloneable interfaces. 86# 87clone_up() 88{ 89 _prefix= 90 _list= 91 for ifn in ${cloned_interfaces}; do 92 ifconfig ${ifn} create 93 if $? ; then 94 _list="${_list}${_prefix}${ifn}" 95 [ -z "$_prefix" ] && _prefix=' ' 96 fi 97 done 98 debug "Cloned: ${_list}" 99} 100 101# Destroy cloned interfaces. Destroyed interfaces are echoed 102# to standard output. 103# 104clone_down() 105{ 106 _prefix= 107 _list= 108 for ifn in ${cloned_interfaces}; do 109 ifconfig ${ifn} destroy 110 if $? ; then 111 _list="${_list}${_prefix}${ifn}" 112 [ -z "$_prefix" ] && _prefix=' ' 113 fi 114 done 115 debug "Destroyed clones: ${_list}" 116} 117 118gif_up() { 119 case ${gif_interfaces} in 120 [Nn][Oo] | '') 121 ;; 122 *) 123 for i in ${gif_interfaces}; do 124 eval peers=\$gifconfig_$i 125 case ${peers} in 126 '') 127 continue 128 ;; 129 *) 130 ifconfig $i create >/dev/null 2>&1 131 ifconfig $i tunnel ${peers} 132 ifconfig $i up 133 ;; 134 esac 135 done 136 ;; 137 esac 138} 139 140# 141# ipx_up ifn 142# Configure any IPX addresses for interface $ifn. Returns 0 if IPX 143# arguments were found and configured; returns 1 otherwise. 144# 145ipx_up() 146{ 147 ifn="$1" 148 eval ifconfig_args=\$ifconfig_${ifn}_ipx 149 if [ -n "${ifconfig_args}" ]; then 150 ifconfig ${ifn} ${ifconfig_args} 151 return 0 152 fi 153 return 1 154} 155 156# 157# list_net_interfaces type 158# List all network interfaces. The type of interface returned 159# can be controlled by the type argument. The type 160# argument can be any of the following: 161# nodhcp - all interfaces, excluding DHCP configured interfaces 162# dhcp - list only DHCP configured interfaces 163# If no argument is specified all network interfaces are output. 164# Note that the list always includes cloned interfaces. 165# 166list_net_interfaces() 167{ 168 type=$1 169 170 # Get a list of ALL the interfaces 171 # 172 case ${network_interfaces} in 173 [Aa][Uu][Tt][Oo]) 174 _tmplist="`ifconfig -l`" 175 ;; 176 *) 177 _tmplist="${network_interfaces}" 178 ;; 179 esac 180 _tmplist="${_tmplist} ${cloned_interfaces}" 181 182 if [ -z "$type" ]; then 183 echo $_tmplist 184 return 0 185 fi 186 187 # Separate out dhcp and non-dhcp intefraces 188 # 189 _aprefix= 190 _brefix= 191 for _if in ${_tmplist} ; do 192 eval _ifarg="\$ifconfig_${_if}" 193 case "$_ifarg" in 194 [Dd][Hh][Cc][Pp]) 195 _dhcplist="${_dhcplist}${_aprefix}${_if}" 196 [ -z "$_aprefix" ] && _aprefix=' ' 197 ;; 198 ''|*) 199 _nodhcplist="${_nodhcplist}${_bprefix}${_if}" 200 [ -z "$_bprefix" ] && _bprefix=' ' 201 ;; 202 esac 203 done 204 205 case "$type" in 206 nodhcp) 207 echo $_nodhcplist 208 ;; 209 dhcp) 210 echo $_dhcplist 211 ;; 212 esac 213 return 0 214} 215 216hexdigit() 217{ 218 if [ $1 -lt 10 ]; then 219 echo $1 220 else 221 case $1 in 222 10) echo a ;; 223 11) echo b ;; 224 12) echo c ;; 225 13) echo d ;; 226 14) echo e ;; 227 15) echo f ;; 228 esac 229 fi 230} 231 232hexprint() 233{ 234 val=$1 235 str='' 236 237 dig=`hexdigit $((${val} & 15))` 238 str=${dig}${str} 239 val=$((${val} >> 4)) 240 while [ ${val} -gt 0 ]; do 241 dig=`hexdigit $((${val} & 15))` 242 str=${dig}${str} 243 val=$((${val} >> 4)) 244 done 245 246 echo ${str} 247} 248 249# Setup the interfaces for IPv6 250network6_interface_setup() 251{ 252 interfaces=$* 253 rtsol_interfaces='' 254 case ${ipv6_gateway_enable} in 255 [Yy][Ee][Ss]) 256 rtsol_available=no 257 ;; 258 *) 259 rtsol_available=yes 260 ;; 261 esac 262 for i in $interfaces; do 263 rtsol_interface=yes 264 eval prefix=\$ipv6_prefix_$i 265 if [ -n "${prefix}" ]; then 266 rtsol_available=no 267 rtsol_interface=no 268 laddr=`network6_getladdr $i` 269 hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'` 270 for j in ${prefix}; do 271 address=$j\:${hostid} 272 ifconfig $i inet6 ${address} prefixlen 64 alias 273 274 case ${ipv6_gateway_enable} in 275 [Yy][Ee][Ss]) 276 # subnet-router anycast address 277 # (rfc2373) 278 ifconfig $i inet6 $j:: prefixlen 64 \ 279 alias anycast 280 ;; 281 esac 282 done 283 fi 284 eval ipv6_ifconfig=\$ipv6_ifconfig_$i 285 if [ -n "${ipv6_ifconfig}" ]; then 286 rtsol_available=no 287 rtsol_interface=no 288 ifconfig $i inet6 ${ipv6_ifconfig} alias 289 fi 290 291 if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ] 292 then 293 case ${i} in 294 lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*) 295 ;; 296 *) 297 rtsol_interfaces="${rtsol_interfaces} ${i}" 298 ;; 299 esac 300 else 301 ifconfig $i inet6 302 fi 303 done 304 305 if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then 306 # Act as endhost - automatically configured. 307 # You can configure only single interface, as 308 # specification assumes that autoconfigured host has 309 # single interface only. 310 sysctl net.inet6.ip6.accept_rtadv=1 311 set ${rtsol_interfaces} 312 ifconfig $1 up 313 rtsol $1 314 fi 315 316 for i in $interfaces; do 317 alias=0 318 while : ; do 319 eval ipv6_ifconfig=\$ipv6_ifconfig_${i}_alias${alias} 320 if [ -z "${ipv6_ifconfig}" ]; then 321 break; 322 fi 323 ifconfig $i inet6 ${ipv6_ifconfig} alias 324 alias=$((${alias} + 1)) 325 done 326 done 327} 328 329# Setup IPv6 to IPv4 mapping 330network6_stf_setup() 331{ 332 case ${stf_interface_ipv4addr} in 333 [Nn][Oo] | '') 334 ;; 335 *) 336 # assign IPv6 addr and interface route for 6to4 interface 337 stf_prefixlen=$((16+${stf_interface_ipv4plen:-0})) 338 OIFS="$IFS" 339 IFS=".$IFS" 340 set ${stf_interface_ipv4addr} 341 IFS="$OIFS" 342 hexfrag1=`hexprint $(($1*256 + $2))` 343 hexfrag2=`hexprint $(($3*256 + $4))` 344 ipv4_in_hexformat="${hexfrag1}:${hexfrag2}" 345 case ${stf_interface_ipv6_ifid} in 346 [Aa][Uu][Tt][Oo] | '') 347 for i in ${ipv6_network_interfaces}; do 348 laddr=`network6_getladdr ${i}` 349 case ${laddr} in 350 '') 351 ;; 352 *) 353 break 354 ;; 355 esac 356 done 357 stf_interface_ipv6_ifid=`expr "${laddr}" : \ 358 'fe80::\(.*\)%\(.*\)'` 359 case ${stf_interface_ipv6_ifid} in 360 '') 361 stf_interface_ipv6_ifid=0:0:0:1 362 ;; 363 esac 364 ;; 365 esac 366 ifconfig stf0 create >/dev/null 2>&1 367 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \ 368 prefixlen ${stf_prefixlen} 369 # disallow packets to malicious 6to4 prefix 370 route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject 371 route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject 372 route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject 373 route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject 374 ;; 375 esac 376} 377 378# Setup static routes 379network6_static_routes_setup() 380{ 381 # Set up any static routes. 382 case ${ipv6_defaultrouter} in 383 [Nn][Oo] | '') 384 ;; 385 *) 386 ipv6_static_routes="default ${ipv6_static_routes}" 387 ipv6_route_default="default ${ipv6_defaultrouter}" 388 ;; 389 esac 390 case ${ipv6_static_routes} in 391 [Nn][Oo] | '') 392 ;; 393 *) 394 for i in ${ipv6_static_routes}; do 395 eval ipv6_route_args=\$ipv6_route_${i} 396 route add -inet6 ${ipv6_route_args} 397 done 398 ;; 399 esac 400} 401 402# Setup faith 403network6_faith_setup() 404{ 405 case ${ipv6_faith_prefix} in 406 [Nn][Oo] | '') 407 ;; 408 *) 409 sysctl net.inet6.ip6.keepfaith=1 410 ifconfig faith0 create >/dev/null 2>&1 411 ifconfig faith0 up 412 for prefix in ${ipv6_faith_prefix}; do 413 prefixlen=`expr "${prefix}" : ".*/\(.*\)"` 414 case ${prefixlen} in 415 '') 416 prefixlen=96 417 ;; 418 *) 419 prefix=`expr "${prefix}" : \ 420 "\(.*\)/${prefixlen}"` 421 ;; 422 esac 423 route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1 424 route change -inet6 ${prefix} -prefixlen ${prefixlen} \ 425 -ifp faith0 426 done 427 ;; 428 esac 429} 430 431# Install the "default interface" to kernel, which will be used 432# as the default route when there's no router. 433network6_default_interface_setup() 434{ 435 # Choose IPv6 default interface if it is not clearly specified. 436 case ${ipv6_default_interface} in 437 '') 438 for i in ${ipv6_network_interfaces}; do 439 case $i in 440 lo0|faith[0-9]*) 441 continue 442 ;; 443 esac 444 laddr=`network6_getladdr $i exclude_tentative` 445 case ${laddr} in 446 '') 447 ;; 448 *) 449 ipv6_default_interface=$i 450 break 451 ;; 452 esac 453 done 454 ;; 455 esac 456 457 # Disallow unicast packets without outgoing scope identifiers, 458 # or route such packets to a "default" interface, if it is specified. 459 route add -inet6 fe80:: -prefixlen 10 ::1 -reject 460 case ${ipv6_default_interface} in 461 [Nn][Oo] | '') 462 route add -inet6 ff02:: -prefixlen 16 ::1 -reject 463 ;; 464 *) 465 laddr=`network6_getladdr ${ipv6_default_interface}` 466 route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \ 467 -cloning 468 469 # Disable installing the default interface with the 470 # case net.inet6.ip6.forwarding=0 and 471 # net.inet6.ip6.accept_rtadv=0, due to avoid conflict 472 # between the default router list and the manual 473 # configured default route. 474 case ${ipv6_gateway_enable} in 475 [Yy][Ee][Ss]) 476 ;; 477 *) 478 if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ] 479 then 480 ndp -I ${ipv6_default_interface} 481 fi 482 ;; 483 esac 484 ;; 485 esac 486} 487 488network6_getladdr() 489{ 490 ifconfig $1 2>/dev/null | while read proto addr rest; do 491 case ${proto} in 492 inet6) 493 case ${addr} in 494 fe80::*) 495 if [ -z "$2" ]; then 496 echo ${addr} 497 return 498 fi 499 case ${rest} in 500 *tentative*) 501 continue 502 ;; 503 *) 504 echo ${addr} 505 return 506 esac 507 esac 508 esac 509 done 510} 511