network.subr revision 188118
11638Srgrimes# 21638Srgrimes# Copyright (c) 2003 The FreeBSD Project. All rights reserved. 31638Srgrimes# 41638Srgrimes# Redistribution and use in source and binary forms, with or without 51638Srgrimes# modification, are permitted provided that the following conditions 61638Srgrimes# are met: 71638Srgrimes# 1. Redistributions of source code must retain the above copyright 81638Srgrimes# notice, this list of conditions and the following disclaimer. 91638Srgrimes# 2. Redistributions in binary form must reproduce the above copyright 101638Srgrimes# notice, this list of conditions and the following disclaimer in the 111638Srgrimes# documentation and/or other materials provided with the distribution. 121638Srgrimes# 131638Srgrimes# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 141638Srgrimes# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 151638Srgrimes# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 161638Srgrimes# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 171638Srgrimes# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 181638Srgrimes# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 191638Srgrimes# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 201638Srgrimes# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 211638Srgrimes# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 221638Srgrimes# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 231638Srgrimes# SUCH DAMAGE. 241638Srgrimes# 251638Srgrimes# $FreeBSD: head/etc/network.subr 188118 2009-02-04 18:20:27Z thompsa $ 261638Srgrimes# 271638Srgrimes 281638Srgrimes# 291638Srgrimes# Subroutines commonly used from network startup scripts. 301638Srgrimes# Requires that rc.conf be loaded first. 311638Srgrimes# 321638Srgrimes 331638Srgrimes# ifn_start ifn 341638Srgrimes# Bring up and configure an interface. If some configuration is applied 351638Srgrimes# print the interface configuration. 361638Srgrimes# 371638Srgrimesifn_start() 381638Srgrimes{ 391638Srgrimes local ifn cfg 401638Srgrimes ifn="$1" 411638Srgrimes cfg=1 421638Srgrimes 431638Srgrimes [ -z "$ifn" ] && err 1 "ifn_start called without an interface" 441638Srgrimes 451638Srgrimes ifscript_up ${ifn} && cfg=0 461638Srgrimes ifconfig_up ${ifn} && cfg=0 471638Srgrimes ipv4_up ${ifn} && cfg=0 481638Srgrimes ipx_up ${ifn} && cfg=0 491638Srgrimes childif_create ${ifn} 501638Srgrimes 511638Srgrimes return $cfg 521638Srgrimes} 531638Srgrimes 541638Srgrimes# ifn_start ifn 551638Srgrimes# Shutdown and de-configure an interface. If action is taken print the 561638Srgrimes# interface name. 571638Srgrimes# 581638Srgrimesifn_stop() 591638Srgrimes{ 601638Srgrimes local ifn cfg 611638Srgrimes ifn="$1" 621638Srgrimes cfg=1 631638Srgrimes 641638Srgrimes [ -z "$ifn" ] && return 1 651638Srgrimes 661638Srgrimes ipx_down ${ifn} && cfg=0 671638Srgrimes ipv4_down ${ifn} && cfg=0 681638Srgrimes ifconfig_down ${ifn} && cfg=0 691638Srgrimes ifscript_down ${ifn} && cfg=0 701638Srgrimes childif_destroy ${ifn} 711638Srgrimes 721638Srgrimes return $cfg 731638Srgrimes} 741638Srgrimes 751638Srgrimes# ifconfig_up if 761638Srgrimes# Evaluate ifconfig(8) arguments for interface $if and 771638Srgrimes# run ifconfig(8) with those arguments. It returns 0 if 781638Srgrimes# arguments were found and executed or 1 if the interface 791638Srgrimes# had no arguments. Pseudo arguments DHCP and WPA are handled 801638Srgrimes# here. 811638Srgrimes# 821638Srgrimesifconfig_up() 831638Srgrimes{ 841638Srgrimes _cfg=1 851638Srgrimes 861638Srgrimes ifconfig_args=`ifconfig_getargs $1` 871638Srgrimes if [ -n "${ifconfig_args}" ]; then 881638Srgrimes ifconfig $1 ${ifconfig_args} 891638Srgrimes ifconfig $1 up 901638Srgrimes _cfg=0 911638Srgrimes fi 921638Srgrimes 931638Srgrimes if wpaif $1; then 941638Srgrimes /etc/rc.d/wpa_supplicant start $1 951638Srgrimes _cfg=0 # XXX: not sure this should count 961638Srgrimes fi 971638Srgrimes 981638Srgrimes if dhcpif $1; then 991638Srgrimes if [ $_cfg -ne 0 ] ; then 1001638Srgrimes ifconfig $1 up 1011638Srgrimes fi 1021638Srgrimes if syncdhcpif $1; then 1031638Srgrimes /etc/rc.d/dhclient start $1 1041638Srgrimes fi 1051638Srgrimes _cfg=0 1061638Srgrimes fi 1071638Srgrimes 1081638Srgrimes return $_cfg 1091638Srgrimes} 1101638Srgrimes 1111638Srgrimes# ifconfig_down if 1121638Srgrimes# returns 1 if wpa_supplicant or dhclient was stopped or 1131638Srgrimes# the interface exists. 1141638Srgrimes# 1151638Srgrimesifconfig_down() 1161638Srgrimes{ 1171638Srgrimes [ -z "$1" ] && return 1 1181638Srgrimes _cfg=1 1191638Srgrimes 1201638Srgrimes if wpaif $1; then 1211638Srgrimes /etc/rc.d/wpa_supplicant stop $1 1221638Srgrimes _cfg=0 1231638Srgrimes fi 1241638Srgrimes 1251638Srgrimes if dhcpif $1; then 1261638Srgrimes /etc/rc.d/dhclient stop $1 1271638Srgrimes _cfg=0 1281638Srgrimes fi 1291638Srgrimes 1301638Srgrimes if ifexists $1; then 1311638Srgrimes ifconfig $1 down 1321638Srgrimes _cfg=0 1331638Srgrimes fi 1341638Srgrimes 1351638Srgrimes return $_cfg 1361638Srgrimes} 1371638Srgrimes 1381638Srgrimes# get_if_var if var [default] 1391638Srgrimes# Return the value of the pseudo-hash corresponding to $if where 1401638Srgrimes# $var is a string containg the sub-string "IF" which will be 1411638Srgrimes# replaced with $if after the characters defined in _punct are 1421638Srgrimes# replaced with '_'. If the variable is unset, replace it with 1431638Srgrimes# $default if given. 1441638Srgrimesget_if_var() 1451638Srgrimes{ 1461638Srgrimes if [ $# -ne 2 -a $# -ne 3 ]; then 1471638Srgrimes err 3 'USAGE: get_if_var name var [default]' 1481638Srgrimes fi 1491638Srgrimes 1501638Srgrimes _if=$1 1511638Srgrimes _punct=". - / +" 1521638Srgrimes for _punct_c in $_punct; do 1531638Srgrimes _if=`ltr ${_if} ${_punct_c} '_'` 1541638Srgrimes done 1551638Srgrimes _var=$2 1561638Srgrimes _default=$3 1571638Srgrimes 1581638Srgrimes prefix=${_var%%IF*} 1591638Srgrimes suffix=${_var##*IF} 1601638Srgrimes eval echo \${${prefix}${_if}${suffix}-${_default}} 1611638Srgrimes} 1621638Srgrimes 1631638Srgrimes# _ifconfig_getargs if 1641638Srgrimes# Echos the arguments for the supplied interface to stdout. 1651638Srgrimes# returns 1 if empty. In general, ifconfig_getargs should be used 1661638Srgrimes# outside this file. 1671638Srgrimes_ifconfig_getargs() 1681638Srgrimes{ 1691638Srgrimes _ifn=$1 1701638Srgrimes if [ -z "$_ifn" ]; then 1711638Srgrimes return 1 172 fi 173 174 get_if_var $_ifn ifconfig_IF "$ifconfig_DEFAULT" 175} 176 177# ifconfig_getargs if 178# Takes the result from _ifconfig_getargs and removes pseudo 179# args such as DHCP and WPA. 180ifconfig_getargs() 181{ 182 _tmpargs=`_ifconfig_getargs $1` 183 if [ $? -eq 1 ]; then 184 return 1 185 fi 186 _args= 187 188 for _arg in $_tmpargs; do 189 case $_arg in 190 [Dd][Hh][Cc][Pp]) ;; 191 [Nn][Oo][Aa][Uu][Tt][Oo]) ;; 192 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 193 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 194 [Ww][Pp][Aa]) ;; 195 *) 196 _args="$_args $_arg" 197 ;; 198 esac 199 done 200 201 echo $_args 202} 203 204# autoif 205# Returns 0 if the interface should be automaticly configured at 206# boot time and 1 otherwise. 207autoif() 208{ 209 _tmpargs=`_ifconfig_getargs $1` 210 for _arg in $_tmpargs; do 211 case $_arg in 212 [Nn][Oo][Aa][Uu][Tt][Oo]) 213 return 1 214 ;; 215 esac 216 done 217 return 0 218} 219 220# dhcpif if 221# Returns 0 if the interface is a DHCP interface and 1 otherwise. 222dhcpif() 223{ 224 _tmpargs=`_ifconfig_getargs $1` 225 for _arg in $_tmpargs; do 226 case $_arg in 227 [Dd][Hh][Cc][Pp]) 228 return 0 229 ;; 230 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 231 return 0 232 ;; 233 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 234 return 0 235 ;; 236 esac 237 done 238 return 1 239} 240 241# syncdhcpif 242# Returns 0 if the interface should be configured synchronously and 243# 1 otherwise. 244syncdhcpif() 245{ 246 _tmpargs=`_ifconfig_getargs $1` 247 for _arg in $_tmpargs; do 248 case $_arg in 249 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 250 return 1 251 ;; 252 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 253 return 0 254 ;; 255 esac 256 done 257 if checkyesno synchronous_dhclient; then 258 return 0 259 else 260 return 1 261 fi 262} 263 264# wpaif if 265# Returns 0 if the interface is a WPA interface and 1 otherwise. 266wpaif() 267{ 268 _tmpargs=`_ifconfig_getargs $1` 269 for _arg in $_tmpargs; do 270 case $_arg in 271 [Ww][Pp][Aa]) 272 return 0 273 ;; 274 esac 275 done 276 return 1 277} 278 279# ipv6if if 280# Returns 0 if the interface should be configured for IPv6 and 281# 1 otherwise. 282ipv6if() 283{ 284 if ! checkyesno ipv6_enable; then 285 return 1 286 fi 287 case "${ipv6_network_interfaces}" in 288 [Aa][Uu][Tt][Oo]) 289 return 0 290 ;; 291 ''|[Nn][Oo][Nn][Ee]) 292 return 1 293 ;; 294 esac 295 for v6if in ${ipv6_network_interfaces}; do 296 if [ "${v6if}" = "${1}" ]; then 297 return 0 298 fi 299 done 300 return 1 301} 302 303# ifexists if 304# Returns 0 if the interface exists and 1 otherwise. 305ifexists() 306{ 307 ifconfig -n $1 > /dev/null 2>&1 308} 309 310# ipv4_up if 311# add IPv4 addresses to the interface $if 312ipv4_up() 313{ 314 _if=$1 315 ifalias_up ${_if} 316 ipv4_addrs_common ${_if} alias 317} 318 319# ipv4_down if 320# remove IPv4 addresses from the interface $if 321ipv4_down() 322{ 323 _if=$1 324 _ifs="^" 325 _ret=1 326 327 ifexists ${_if} || return 1 328 329 inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`" 330 331 oldifs="$IFS" 332 IFS="$_ifs" 333 for _inet in $inetList ; do 334 # get rid of extraneous line 335 [ -z "$_inet" ] && break 336 337 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 338 339 IFS="$oldifs" 340 ifconfig ${_if} ${_inet} delete 341 IFS="$_ifs" 342 _ret=0 343 done 344 IFS="$oldifs" 345 346 ifalias_down ${_if} && _ret=0 347 ipv4_addrs_common ${_if} -alias && _ret=0 348 349 return $_ret 350} 351 352# ipv4_addrs_common if action 353# Evaluate the ifconfig_if_ipv4 arguments for interface $if 354# and use $action to add or remove IPv4 addresses from $if. 355ipv4_addrs_common() 356{ 357 _ret=1 358 _if=$1 359 _action=$2 360 361 # get ipv4-addresses 362 cidr_addr=`get_if_var $_if ipv4_addrs_IF` 363 364 for _cidr in ${cidr_addr}; do 365 _ipaddr=${_cidr%%/*} 366 _netmask="/"${_cidr##*/} 367 _range=${_ipaddr##*.} 368 _ipnet=${_ipaddr%.*} 369 _iplow=${_range%-*} 370 _iphigh=${_range#*-} 371 372 # clear netmask when removing aliases 373 if [ "${_action}" = "-alias" ]; then 374 _netmask="" 375 fi 376 377 _ipcount=${_iplow} 378 while [ "${_ipcount}" -le "${_iphigh}" ]; do 379 eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}" 380 _ipcount=$((${_ipcount}+1)) 381 _ret=0 382 383 # only the first ipaddr in a subnet need the real netmask 384 if [ "${_action}" != "-alias" ]; then 385 _netmask="/32" 386 fi 387 done 388 done 389 return $_ret 390} 391 392# ifalias_up if 393# Configure aliases for network interface $if. 394# It returns 0 if at least one alias was configured or 395# 1 if there were none. 396# 397ifalias_up() 398{ 399 _ret=1 400 alias=0 401 while : ; do 402 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 403 if [ -n "${ifconfig_args}" ]; then 404 ifconfig $1 ${ifconfig_args} alias 405 alias=$((${alias} + 1)) 406 _ret=0 407 else 408 break 409 fi 410 done 411 return $_ret 412} 413 414#ifalias_down if 415# Remove aliases for network interface $if. 416# It returns 0 if at least one alias was removed or 417# 1 if there were none. 418# 419ifalias_down() 420{ 421 _ret=1 422 alias=0 423 while : ; do 424 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 425 if [ -n "${ifconfig_args}" ]; then 426 ifconfig $1 ${ifconfig_args} -alias 427 alias=$((${alias} + 1)) 428 _ret=0 429 else 430 break 431 fi 432 done 433 return $_ret 434} 435 436# ifscript_up if 437# Evaluate a startup script for the $if interface. 438# It returns 0 if a script was found and processed or 439# 1 if no script was found. 440# 441ifscript_up() 442{ 443 if [ -r /etc/start_if.$1 ]; then 444 . /etc/start_if.$1 445 return 0 446 fi 447 return 1 448} 449 450# ifscript_down if 451# Evaluate a shutdown script for the $if interface. 452# It returns 0 if a script was found and processed or 453# 1 if no script was found. 454# 455ifscript_down() 456{ 457 if [ -r /etc/stop_if.$1 ]; then 458 . /etc/stop_if.$1 459 return 0 460 fi 461 return 1 462} 463 464# Create cloneable interfaces. 465# 466clone_up() 467{ 468 _prefix= 469 _list= 470 for ifn in ${cloned_interfaces}; do 471 ifconfig ${ifn} create `get_if_var ${ifn} create_args_IF` 472 if [ $? -eq 0 ]; then 473 _list="${_list}${_prefix}${ifn}" 474 [ -z "$_prefix" ] && _prefix=' ' 475 fi 476 done 477 debug "Cloned: ${_list}" 478} 479 480# Destroy cloned interfaces. Destroyed interfaces are echoed 481# to standard output. 482# 483clone_down() 484{ 485 _prefix= 486 _list= 487 for ifn in ${cloned_interfaces}; do 488 ifconfig ${ifn} destroy 489 if [ $? -eq 0 ]; then 490 _list="${_list}${_prefix}${ifn}" 491 [ -z "$_prefix" ] && _prefix=' ' 492 fi 493 done 494 debug "Destroyed clones: ${_list}" 495} 496 497# Create and configure child interfaces. 498# Return 0 if child interfaces are created. 499# 500childif_create() 501{ 502 local cfg child child_wlans create_args ifn i 503 cfg=1 504 505 ifn=$1 506 507 # Create wireless interfaces 508 child_wlans=`get_if_var $ifn wlans_IF` 509 510 for child in ${child_wlans}; do 511 create_args="wlandev $ifn `get_if_var $child create_args_IF`" 512 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then 513 ifconfig $child create ${create_args} && cfg=0 514 else 515 i=`ifconfig wlan create ${create_args}` 516 ifconfig $i name $child && cfg=0 517 fi 518 if autoif $child; then 519 ifn_start $child 520 fi 521 done 522 523 return ${cfg} 524} 525 526# Destroy child interfaces. 527# 528childif_destroy() 529{ 530 local cfg child child_wlans ifn 531 532 child_wlans="`get_if_var $ifn wlans_IF` `get_if_var $ifn vaps_IF`" 533 for child in ${child_wlans}; do 534 ifconfig $child destroy && cfg=0 535 done 536} 537 538# Create netgraph nodes. 539# 540ng_mkpeer() { 541 ngctl -f - 2> /dev/null <<EOF 542mkpeer $* 543msg dummy nodeinfo 544EOF 545} 546 547ng_create_one() { 548 ng_mkpeer $* | while read line; do 549 t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'` 550 if [ -n "${t}" ]; then 551 echo ${t} 552 return 553 fi 554 done 555} 556 557gif_up() { 558 for i in ${gif_interfaces}; do 559 peers=`get_if_var $i gifconfig_IF` 560 case ${peers} in 561 '') 562 continue 563 ;; 564 *) 565 if expr $i : 'gif[0-9][0-9]*$' >/dev/null 2>&1; then 566 ifconfig $i create >/dev/null 2>&1 567 else 568 gif=`ifconfig gif create` 569 ifconfig $gif name $i 570 fi 571 ifconfig $i tunnel ${peers} 572 ifconfig $i up 573 ;; 574 esac 575 done 576} 577 578# ng_fec_create ifn 579# Configure Fast EtherChannel for interface $ifn. Returns 0 if FEC 580# arguments were found and configured; returns !0 otherwise. 581ng_fec_create() { 582 local req_iface iface bogus 583 req_iface="$1" 584 585 ngctl shutdown ${req_iface}: > /dev/null 2>&1 586 587 bogus="" 588 while true; do 589 iface=`ng_create_one fec dummy fec` 590 if [ -z "${iface}" ]; then 591 exit 2 592 fi 593 if [ "${iface}" = "${req_iface}" ]; then 594 break 595 fi 596 bogus="${bogus} ${iface}" 597 done 598 599 for iface in ${bogus}; do 600 ngctl shutdown ${iface}: 601 done 602} 603 604fec_up() { 605 for i in ${fec_interfaces}; do 606 ng_fec_create $i 607 for j in `get_if_var $i fecconfig_IF`; do 608 case ${j} in 609 '') 610 continue 611 ;; 612 *) 613 ngctl msg ${i}: add_iface "\"${j}\"" 614 ;; 615 esac 616 done 617 done 618} 619 620# 621# ipx_up ifn 622# Configure any IPX addresses for interface $ifn. Returns 0 if IPX 623# arguments were found and configured; returns 1 otherwise. 624# 625ipx_up() 626{ 627 ifn="$1" 628 ifconfig_args=`get_if_var $ifn ifconfig_IF_ipx` 629 if [ -n "${ifconfig_args}" ]; then 630 ifconfig ${ifn} ${ifconfig_args} 631 return 0 632 fi 633 return 1 634} 635 636# ipx_down ifn 637# Remove IPX addresses for interface $ifn. Returns 0 if IPX 638# addresses were found and unconfigured. It returns 1, otherwise. 639# 640ipx_down() 641{ 642 [ -z "$1" ] && return 1 643 _ifs="^" 644 _ret=1 645 646 ifexists $1 || return 1 647 648 ipxList="`ifconfig $1 | grep 'ipx ' | tr "\n" "$_ifs"`" 649 650 oldifs="$IFS" 651 IFS="$_ifs" 652 for _ipx in $ipxList ; do 653 # get rid of extraneous line 654 [ -z "$_ipx" ] && break 655 656 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 657 658 IFS="$oldifs" 659 ifconfig $1 ${_ipx} delete 660 IFS="$_ifs" 661 _ret=0 662 done 663 IFS="$oldifs" 664 665 return $_ret 666} 667 668# ifnet_rename 669# Rename all requested interfaces. 670# 671ifnet_rename() 672{ 673 674 _ifn_list="`ifconfig -l`" 675 [ -z "$_ifn_list" ] && return 0 676 for _if in ${_ifn_list} ; do 677 _ifname=`get_if_var $_if ifconfig_IF_name` 678 if [ ! -z "$_ifname" ]; then 679 ifconfig $_if name $_ifname 680 fi 681 done 682 return 0 683} 684 685# 686# list_net_interfaces type 687# List all network interfaces. The type of interface returned 688# can be controlled by the type argument. The type 689# argument can be any of the following: 690# nodhcp - all interfaces, excluding DHCP configured interfaces 691# dhcp - list only DHCP configured interfaces 692# If no argument is specified all network interfaces are output. 693# Note that the list will include cloned interfaces if applicable. 694# Cloned interfaces must already exist to have a chance to appear 695# in the list if ${network_interfaces} is set to `auto'. 696# 697list_net_interfaces() 698{ 699 type=$1 700 701 # Get a list of ALL the interfaces and make lo0 first if it's there. 702 # 703 case ${network_interfaces} in 704 [Aa][Uu][Tt][Oo]) 705 _prefix='' 706 _autolist="`ifconfig -l`" 707 _lo= 708 for _if in ${_autolist} ; do 709 if autoif $_if; then 710 if [ "$_if" = "lo0" ]; then 711 _lo="lo0 " 712 else 713 _tmplist="${_tmplist}${_prefix}${_if}" 714 [ -z "$_prefix" ] && _prefix=' ' 715 fi 716 fi 717 done 718 _tmplist="${_lo}${_tmplist}" 719 ;; 720 *) 721 if [ -z "$type" ]; then 722 warn "Values of network_interfaces other than" \ 723 "AUTO are deprecated" 724 fi 725 _tmplist="${network_interfaces} ${cloned_interfaces}" 726 ;; 727 esac 728 729 if [ -z "$type" ]; then 730 echo $_tmplist 731 return 0 732 fi 733 734 # Separate out dhcp and non-dhcp interfaces 735 # 736 _aprefix= 737 _bprefix= 738 for _if in ${_tmplist} ; do 739 if dhcpif $_if; then 740 _dhcplist="${_dhcplist}${_aprefix}${_if}" 741 [ -z "$_aprefix" ] && _aprefix=' ' 742 elif [ -n "`_ifconfig_getargs $_if`" ]; then 743 _nodhcplist="${_nodhcplist}${_bprefix}${_if}" 744 [ -z "$_bprefix" ] && _bprefix=' ' 745 fi 746 done 747 748 case "$type" in 749 nodhcp) 750 echo $_nodhcplist 751 ;; 752 dhcp) 753 echo $_dhcplist 754 ;; 755 esac 756 return 0 757} 758 759# get_default_if -address_family 760# Get the interface of the default route for the given address family. 761# The -address_family argument must be suitable passing to route(8). 762# 763get_default_if() 764{ 765 routeget="`route -n get $1 default 2>/dev/null`" 766 oldifs="$IFS" 767 IFS=" 768" 769 defif= 770 for line in $routeget ; do 771 case $line in 772 *interface:*) 773 defif=${line##*: } 774 ;; 775 esac 776 done 777 IFS=${oldifs} 778 779 echo $defif 780} 781 782hexdigit() 783{ 784 if [ $1 -lt 10 ]; then 785 echo $1 786 else 787 case $1 in 788 10) echo a ;; 789 11) echo b ;; 790 12) echo c ;; 791 13) echo d ;; 792 14) echo e ;; 793 15) echo f ;; 794 esac 795 fi 796} 797 798hexprint() 799{ 800 val=$1 801 str='' 802 803 dig=`hexdigit $((${val} & 15))` 804 str=${dig}${str} 805 val=$((${val} >> 4)) 806 while [ ${val} -gt 0 ]; do 807 dig=`hexdigit $((${val} & 15))` 808 str=${dig}${str} 809 val=$((${val} >> 4)) 810 done 811 812 echo ${str} 813} 814 815# Setup the interfaces for IPv6 816network6_interface_setup() 817{ 818 interfaces=$* 819 rtsol_interfaces='' 820 case ${ipv6_gateway_enable} in 821 [Yy][Ee][Ss]) 822 rtsol_available=no 823 ;; 824 *) 825 rtsol_available=yes 826 ;; 827 esac 828 for i in $interfaces; do 829 rtsol_interface=yes 830 prefix=`get_if_var $i ipv6_prefix_IF` 831 if [ -n "${prefix}" ]; then 832 rtsol_available=no 833 rtsol_interface=no 834 laddr=`network6_getladdr $i` 835 hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'` 836 for j in ${prefix}; do 837 address=$j\:${hostid} 838 ifconfig $i inet6 ${address} prefixlen 64 alias 839 840 case ${ipv6_gateway_enable} in 841 [Yy][Ee][Ss]) 842 # subnet-router anycast address 843 # (rfc2373) 844 ifconfig $i inet6 $j:: prefixlen 64 \ 845 alias anycast 846 ;; 847 esac 848 done 849 fi 850 ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF` 851 if [ -n "${ipv6_ifconfig}" ]; then 852 rtsol_available=no 853 rtsol_interface=no 854 ifconfig $i inet6 ${ipv6_ifconfig} alias 855 fi 856 857 if [ ${rtsol_available} = yes -a ${rtsol_interface} = yes ] 858 then 859 case ${i} in 860 lo0|gif[0-9]*|stf[0-9]*|faith[0-9]*|lp[0-9]*|sl[0-9]*|tun[0-9]*|pflog[0-9]*|pfsync[0-9]*) 861 ;; 862 *) 863 rtsol_interfaces="${rtsol_interfaces} ${i}" 864 ;; 865 esac 866 else 867 ifconfig $i inet6 868 fi 869 done 870 871 if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then 872 # Act as endhost - automatically configured. 873 # You can configure only single interface, as 874 # specification assumes that autoconfigured host has 875 # single interface only. 876 sysctl net.inet6.ip6.accept_rtadv=1 877 set ${rtsol_interfaces} 878 ifconfig $1 up 879 rtsol ${rtsol_flags} $1 880 fi 881 882 for i in $interfaces; do 883 alias=0 884 while : ; do 885 ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF_alias${alias}` 886 if [ -z "${ipv6_ifconfig}" ]; then 887 break; 888 fi 889 ifconfig $i inet6 ${ipv6_ifconfig} alias 890 alias=$((${alias} + 1)) 891 done 892 done 893} 894 895# Setup IPv6 to IPv4 mapping 896network6_stf_setup() 897{ 898 case ${stf_interface_ipv4addr} in 899 [Nn][Oo] | '') 900 ;; 901 *) 902 # assign IPv6 addr and interface route for 6to4 interface 903 stf_prefixlen=$((16+${stf_interface_ipv4plen:-0})) 904 OIFS="$IFS" 905 IFS=".$IFS" 906 set ${stf_interface_ipv4addr} 907 IFS="$OIFS" 908 hexfrag1=`hexprint $(($1*256 + $2))` 909 hexfrag2=`hexprint $(($3*256 + $4))` 910 ipv4_in_hexformat="${hexfrag1}:${hexfrag2}" 911 case ${stf_interface_ipv6_ifid} in 912 [Aa][Uu][Tt][Oo] | '') 913 for i in ${ipv6_network_interfaces}; do 914 laddr=`network6_getladdr ${i}` 915 case ${laddr} in 916 '') 917 ;; 918 *) 919 break 920 ;; 921 esac 922 done 923 stf_interface_ipv6_ifid=`expr "${laddr}" : \ 924 'fe80::\(.*\)%\(.*\)'` 925 case ${stf_interface_ipv6_ifid} in 926 '') 927 stf_interface_ipv6_ifid=0:0:0:1 928 ;; 929 esac 930 ;; 931 esac 932 ifconfig stf0 create >/dev/null 2>&1 933 ifconfig stf0 inet6 2002:${ipv4_in_hexformat}:${stf_interface_ipv6_slaid:-0}:${stf_interface_ipv6_ifid} \ 934 prefixlen ${stf_prefixlen} 935 # disallow packets to malicious 6to4 prefix 936 route add -inet6 2002:e000:: -prefixlen 20 ::1 -reject 937 route add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject 938 route add -inet6 2002:0000:: -prefixlen 24 ::1 -reject 939 route add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject 940 ;; 941 esac 942} 943 944# Setup static routes 945network6_static_routes_setup() 946{ 947 # Set up any static routes. 948 case ${ipv6_defaultrouter} in 949 [Nn][Oo] | '') 950 ;; 951 *) 952 ipv6_static_routes="default ${ipv6_static_routes}" 953 ipv6_route_default="default ${ipv6_defaultrouter}" 954 ;; 955 esac 956 case ${ipv6_static_routes} in 957 [Nn][Oo] | '') 958 ;; 959 *) 960 for i in ${ipv6_static_routes}; do 961 ipv6_route_args=`get_if_var $i ipv6_route_IF` 962 route add -inet6 ${ipv6_route_args} 963 done 964 ;; 965 esac 966} 967 968# Setup faith 969network6_faith_setup() 970{ 971 case ${ipv6_faith_prefix} in 972 [Nn][Oo] | '') 973 ;; 974 *) 975 sysctl net.inet6.ip6.keepfaith=1 976 ifconfig faith0 create >/dev/null 2>&1 977 ifconfig faith0 up 978 for prefix in ${ipv6_faith_prefix}; do 979 prefixlen=`expr "${prefix}" : ".*/\(.*\)"` 980 case ${prefixlen} in 981 '') 982 prefixlen=96 983 ;; 984 *) 985 prefix=`expr "${prefix}" : \ 986 "\(.*\)/${prefixlen}"` 987 ;; 988 esac 989 route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1 990 route change -inet6 ${prefix} -prefixlen ${prefixlen} \ 991 -ifp faith0 992 done 993 ;; 994 esac 995} 996 997# Install the "default interface" to kernel, which will be used 998# as the default route when there's no router. 999network6_default_interface_setup() 1000{ 1001 # Choose IPv6 default interface if it is not clearly specified. 1002 case ${ipv6_default_interface} in 1003 '') 1004 for i in ${ipv6_network_interfaces}; do 1005 case $i in 1006 lo0|faith[0-9]*) 1007 continue 1008 ;; 1009 esac 1010 laddr=`network6_getladdr $i exclude_tentative` 1011 case ${laddr} in 1012 '') 1013 ;; 1014 *) 1015 ipv6_default_interface=$i 1016 break 1017 ;; 1018 esac 1019 done 1020 ;; 1021 esac 1022 1023 # Disallow unicast packets without outgoing scope identifiers, 1024 # or route such packets to a "default" interface, if it is specified. 1025 route add -inet6 fe80:: -prefixlen 10 ::1 -reject 1026 case ${ipv6_default_interface} in 1027 [Nn][Oo] | '') 1028 route add -inet6 ff02:: -prefixlen 16 ::1 -reject 1029 ;; 1030 *) 1031 laddr=`network6_getladdr ${ipv6_default_interface}` 1032 route add -inet6 ff02:: ${laddr} -prefixlen 16 -interface \ 1033 -cloning 1034 1035 # Disable installing the default interface with the 1036 # case net.inet6.ip6.forwarding=0 and 1037 # net.inet6.ip6.accept_rtadv=0, due to avoid conflict 1038 # between the default router list and the manual 1039 # configured default route. 1040 case ${ipv6_gateway_enable} in 1041 [Yy][Ee][Ss]) 1042 ;; 1043 *) 1044 if [ `sysctl -n net.inet6.ip6.accept_rtadv` -eq 1 ] 1045 then 1046 ndp -I ${ipv6_default_interface} 1047 fi 1048 ;; 1049 esac 1050 ;; 1051 esac 1052} 1053 1054network6_getladdr() 1055{ 1056 ifconfig $1 2>/dev/null | while read proto addr rest; do 1057 case ${proto} in 1058 inet6) 1059 case ${addr} in 1060 fe80::*) 1061 if [ -z "$2" ]; then 1062 echo ${addr} 1063 return 1064 fi 1065 case ${rest} in 1066 *tentative*) 1067 continue 1068 ;; 1069 *) 1070 echo ${addr} 1071 return 1072 esac 1073 esac 1074 esac 1075 done 1076} 1077