network.subr revision 325803
1145184Sglebius# 2145184Sglebius# Copyright (c) 2003 The FreeBSD Project. All rights reserved. 3145184Sglebius# 4145184Sglebius# Redistribution and use in source and binary forms, with or without 5145184Sglebius# modification, are permitted provided that the following conditions 6145184Sglebius# are met: 7145184Sglebius# 1. Redistributions of source code must retain the above copyright 8145184Sglebius# notice, this list of conditions and the following disclaimer. 9145184Sglebius# 2. Redistributions in binary form must reproduce the above copyright 10155768Sceri# notice, this list of conditions and the following disclaimer in the 11145184Sglebius# documentation and/or other materials provided with the distribution. 12155458Sglebius# 13145184Sglebius# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 14145184Sglebius# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15216300Ssyrinx# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16216300Ssyrinx# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 17216300Ssyrinx# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18216300Ssyrinx# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19216300Ssyrinx# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20216300Ssyrinx# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21216300Ssyrinx# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22216300Ssyrinx# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23216300Ssyrinx# SUCH DAMAGE. 24145184Sglebius# 25145184Sglebius# $FreeBSD: stable/10/etc/network.subr 325803 2017-11-14 11:02:46Z eugen $ 26165685Smaxim# 27165685SmaximIFCONFIG_CMD="/sbin/ifconfig" 28145184Sglebius: ${netif_ipexpand_max:=2048} 29145184Sglebius 30145184Sglebius# 31216595Ssyrinx# Subroutines commonly used from network startup scripts. 32216300Ssyrinx# Requires that rc.conf be loaded first. 33216595Ssyrinx# 34216595Ssyrinx 35216300Ssyrinx# ifn_start ifn 36216300Ssyrinx# Bring up and configure an interface. If some configuration is 37216300Ssyrinx# applied, print the interface configuration. 38216300Ssyrinx# 39216300Ssyrinxifn_start() 40216300Ssyrinx{ 41216300Ssyrinx local ifn cfg 42145184Sglebius ifn="$1" 43216595Ssyrinx cfg=1 44216595Ssyrinx 45216595Ssyrinx [ -z "$ifn" ] && err 1 "ifn_start called without an interface" 46216595Ssyrinx 47216595Ssyrinx ifscript_up ${ifn} && cfg=0 48216595Ssyrinx ifconfig_up ${ifn} && cfg=0 49216595Ssyrinx if ! noafif $ifn; then 50216595Ssyrinx afexists inet && ipv4_up ${ifn} && cfg=0 51216595Ssyrinx afexists inet6 && ipv6_up ${ifn} && cfg=0 52216595Ssyrinx afexists ipx && ipx_up ${ifn} && cfg=0 53216595Ssyrinx fi 54216595Ssyrinx childif_create ${ifn} && cfg=0 55216595Ssyrinx 56216595Ssyrinx return $cfg 57216595Ssyrinx} 58216595Ssyrinx 59216595Ssyrinx# ifn_stop ifn 60216595Ssyrinx# Shutdown and de-configure an interface. If action is taken, 61216595Ssyrinx# print the interface name. 62216595Ssyrinx# 63216300Ssyrinxifn_stop() 64216300Ssyrinx{ 65216300Ssyrinx local ifn cfg 66216300Ssyrinx ifn="$1" 67216300Ssyrinx cfg=1 68216300Ssyrinx 69216595Ssyrinx [ -z "$ifn" ] && err 1 "ifn_stop called without an interface" 70216300Ssyrinx 71216595Ssyrinx if ! noafif $ifn; then 72216595Ssyrinx afexists ipx && ipx_down ${ifn} && cfg=0 73216300Ssyrinx afexists inet6 && ipv6_down ${ifn} && cfg=0 74216300Ssyrinx afexists inet && ipv4_down ${ifn} && cfg=0 75145184Sglebius fi 76145184Sglebius ifconfig_down ${ifn} && cfg=0 77145184Sglebius ifscript_down ${ifn} && cfg=0 78145184Sglebius childif_destroy ${ifn} && cfg=0 79145184Sglebius 80145184Sglebius return $cfg 81154186Sharti} 82154186Sharti 83154186Sharti# ifn_vnetup ifn 84154186Sharti# Move ifn to the specified vnet jail. 85154186Sharti# 86154186Shartiifn_vnetup() 87154186Sharti{ 88154186Sharti 89154186Sharti ifn_vnet0 $1 vnet 90154186Sharti} 91154186Sharti 92154186Sharti# ifn_vnetdown ifn 93145184Sglebius# Reclaim ifn from the specified vnet jail. 94154186Sharti# 95145184Sglebiusifn_vnetdown() 96145184Sglebius{ 97145184Sglebius 98163823Sharti ifn_vnet0 $1 -vnet 99145184Sglebius} 100145184Sglebius 101145184Sglebius# ifn_vnet0 ifn action 102145184Sglebius# Helper function for ifn_vnetup and ifn_vnetdown. 103145184Sglebius# 104145184Sglebiusifn_vnet0() 105145184Sglebius{ 106145184Sglebius local _ifn _cfg _action _vnet 107145184Sglebius _ifn="$1" 108145184Sglebius _action="$2" 109145184Sglebius _cfg=1 110145184Sglebius 111145184Sglebius if _vnet=$(vnetif $_ifn); then 112145184Sglebius ${IFCONFIG_CMD} $_ifn $_action $_vnet && _cfg=0 113145184Sglebius fi 114145184Sglebius 115145184Sglebius return $_cfg 116216300Ssyrinx} 117216300Ssyrinx 118216300Ssyrinx# ifconfig_up if 119216300Ssyrinx# Evaluate ifconfig(8) arguments for interface $if and 120216300Ssyrinx# run ifconfig(8) with those arguments. It returns 0 if 121216300Ssyrinx# arguments were found and executed or 1 if the interface 122216300Ssyrinx# had no arguments. Pseudo arguments DHCP and WPA are handled 123216300Ssyrinx# here. 124216300Ssyrinx# 125216300Ssyrinxifconfig_up() 126216300Ssyrinx{ 127216300Ssyrinx local _cfg _ifconfig_descr _ipv6_opts ifconfig_args 128216300Ssyrinx _cfg=1 129216300Ssyrinx 130216300Ssyrinx # Make sure lo0 always comes up. 131216300Ssyrinx if [ "$1" = "lo0" ]; then 132216300Ssyrinx _cfg=0 133216300Ssyrinx fi 134216300Ssyrinx 135216300Ssyrinx # inet6 specific 136216300Ssyrinx if ! noafif $1 && afexists inet6; then 137216300Ssyrinx if checkyesno ipv6_activate_all_interfaces; then 138216300Ssyrinx _ipv6_opts="-ifdisabled" 139216300Ssyrinx elif [ "$1" != "lo0" ]; then 140216300Ssyrinx _ipv6_opts="ifdisabled" 141216301Ssyrinx fi 142216300Ssyrinx 143216300Ssyrinx # backward compatibility: $ipv6_enable 144216300Ssyrinx case $ipv6_enable in 145216300Ssyrinx [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 146216300Ssyrinx case $1 in 147216300Ssyrinx bridge[0-9]*) 148216300Ssyrinx # No accept_rtadv by default on if_bridge(4) 149216300Ssyrinx # to avoid a conflict with the member 150216300Ssyrinx # interfaces. 151216300Ssyrinx ;; 152216300Ssyrinx *) 153216300Ssyrinx if ! checkyesno ipv6_gateway_enable; then 154216300Ssyrinx _ipv6_opts="${_ipv6_opts} accept_rtadv" 155216300Ssyrinx fi 156216300Ssyrinx ;; 157216300Ssyrinx esac 158216300Ssyrinx ;; 159216300Ssyrinx esac 160216595Ssyrinx 161216595Ssyrinx case $ipv6_cpe_wanif in 162216300Ssyrinx $1) 163216300Ssyrinx _ipv6_opts="${_ipv6_opts} -no_radr accept_rtadv" 164216595Ssyrinx ;; 165216595Ssyrinx esac 166216300Ssyrinx 167216300Ssyrinx if [ -n "${_ipv6_opts}" ]; then 168216595Ssyrinx ${IFCONFIG_CMD} $1 inet6 ${_ipv6_opts} 169216595Ssyrinx fi 170216595Ssyrinx fi 171216595Ssyrinx 172216300Ssyrinx # ifconfig_IF 173216300Ssyrinx ifconfig_args=`ifconfig_getargs $1` 174216300Ssyrinx if [ -n "${ifconfig_args}" ]; then 175216300Ssyrinx eval ${IFCONFIG_CMD} $1 ${ifconfig_args} 176216300Ssyrinx _cfg=0 177216300Ssyrinx fi 178216300Ssyrinx 179216300Ssyrinx # inet6 specific 180216300Ssyrinx if ! noafif $1 && afexists inet6; then 181216300Ssyrinx # ifconfig_IF_ipv6 182216300Ssyrinx ifconfig_args=`ifconfig_getargs $1 ipv6` 183216300Ssyrinx if [ -n "${ifconfig_args}" ]; then 184216300Ssyrinx # backward compatibility: inet6 keyword 185216300Ssyrinx case "${ifconfig_args}" in 186216300Ssyrinx :*|[0-9a-fA-F]*:*) 187216300Ssyrinx warn "\$ifconfig_$1_ipv6 needs leading" \ 188216300Ssyrinx "\"inet6\" keyword for an IPv6 address." 189216300Ssyrinx ifconfig_args="inet6 ${ifconfig_args}" 190216300Ssyrinx ;; 191216300Ssyrinx esac 192216595Ssyrinx ${IFCONFIG_CMD} $1 inet6 -ifdisabled 193216595Ssyrinx eval ${IFCONFIG_CMD} $1 ${ifconfig_args} 194216300Ssyrinx _cfg=0 195216300Ssyrinx fi 196216300Ssyrinx 197216300Ssyrinx # $ipv6_prefix_IF will be handled in 198216595Ssyrinx # ipv6_prefix_hostid_addr_common(). 199216595Ssyrinx ifconfig_args=`get_if_var $1 ipv6_prefix_IF` 200216595Ssyrinx if [ -n "${ifconfig_args}" ]; then 201216300Ssyrinx ${IFCONFIG_CMD} $1 inet6 -ifdisabled 202216300Ssyrinx _cfg=0 203216300Ssyrinx fi 204216300Ssyrinx 205216300Ssyrinx # backward compatibility: $ipv6_ifconfig_IF 206216595Ssyrinx ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF` 207216595Ssyrinx if [ -n "${ifconfig_args}" ]; then 208216595Ssyrinx warn "\$ipv6_ifconfig_$1 is obsolete." \ 209216300Ssyrinx " Use ifconfig_$1_ipv6 instead." 210216300Ssyrinx ${IFCONFIG_CMD} $1 inet6 -ifdisabled 211216300Ssyrinx eval ${IFCONFIG_CMD} $1 inet6 ${ifconfig_args} 212216300Ssyrinx _cfg=0 213216300Ssyrinx fi 214216300Ssyrinx fi 215216300Ssyrinx 216216300Ssyrinx ifalias $1 link alias 217216300Ssyrinx ifalias $1 ether alias 218216595Ssyrinx 219216595Ssyrinx if [ ${_cfg} -eq 0 ]; then 220216595Ssyrinx ${IFCONFIG_CMD} $1 up 221216595Ssyrinx fi 222216595Ssyrinx 223216595Ssyrinx _ifconfig_descr=`get_if_var $1 ifconfig_IF_descr` 224216595Ssyrinx if [ -n "${_ifconfig_descr}" ]; then 225216595Ssyrinx ${IFCONFIG_CMD} $1 description "${_ifconfig_descr}" 226216595Ssyrinx fi 227216595Ssyrinx 228216595Ssyrinx if wpaif $1; then 229216595Ssyrinx /etc/rc.d/wpa_supplicant start $1 230216595Ssyrinx _cfg=0 # XXX: not sure this should count 231216595Ssyrinx elif hostapif $1; then 232216595Ssyrinx /etc/rc.d/hostapd start $1 233216595Ssyrinx _cfg=0 234216595Ssyrinx fi 235216595Ssyrinx 236216595Ssyrinx if dhcpif $1; then 237216595Ssyrinx if [ $_cfg -ne 0 ] ; then 238216595Ssyrinx ${IFCONFIG_CMD} $1 up 239216595Ssyrinx fi 240216595Ssyrinx if syncdhcpif $1; then 241216595Ssyrinx /etc/rc.d/dhclient start $1 242216595Ssyrinx fi 243216595Ssyrinx _cfg=0 244216595Ssyrinx fi 245216595Ssyrinx 246216595Ssyrinx return $_cfg 247216595Ssyrinx} 248216595Ssyrinx 249216595Ssyrinx# ifconfig_down if 250216595Ssyrinx# returns 1 if wpa_supplicant or dhclient was stopped or 251216595Ssyrinx# the interface exists. 252216595Ssyrinx# 253216595Ssyrinxifconfig_down() 254216595Ssyrinx{ 255216595Ssyrinx local _cfg 256216595Ssyrinx _cfg=1 257216595Ssyrinx 258216595Ssyrinx if wpaif $1; then 259216595Ssyrinx /etc/rc.d/wpa_supplicant stop $1 260216595Ssyrinx _cfg=0 261216595Ssyrinx elif hostapif $1; then 262216595Ssyrinx /etc/rc.d/hostapd stop $1 263216595Ssyrinx _cfg=0 264216595Ssyrinx fi 265216595Ssyrinx 266216595Ssyrinx if dhcpif $1; then 267216595Ssyrinx /etc/rc.d/dhclient stop $1 268216595Ssyrinx _cfg=0 269216595Ssyrinx fi 270216595Ssyrinx 271216595Ssyrinx if ifexists $1; then 272216595Ssyrinx ${IFCONFIG_CMD} $1 down 273216595Ssyrinx _cfg=0 274145184Sglebius fi 275145184Sglebius 276145184Sglebius return $_cfg 277145184Sglebius} 278145184Sglebius 279145184Sglebius# get_if_var if var [default] 280145184Sglebius# Return the value of the pseudo-hash corresponding to $if where 281145184Sglebius# $var is a string containg the sub-string "IF" which will be 282145184Sglebius# replaced with $if after the characters defined in _punct are 283145184Sglebius# replaced with '_'. If the variable is unset, replace it with 284145184Sglebius# $default if given. 285154177Shartiget_if_var() 286154177Sharti{ 287154177Sharti local _if _punct _punct_c _var _default prefix suffix 288154177Sharti 289154177Sharti if [ $# -ne 2 -a $# -ne 3 ]; then 290154177Sharti err 3 'USAGE: get_if_var name var [default]' 291165419Ssyrinx fi 292165419Ssyrinx 293165419Ssyrinx _if=$1 294165419Ssyrinx _punct=".-/+" 295165419Ssyrinx ltr ${_if} "${_punct}" '_' _if 296165419Ssyrinx _var=$2 297210503Ssyrinx _default=$3 298210503Ssyrinx 299210503Ssyrinx prefix=${_var%%IF*} 300210503Ssyrinx suffix=${_var##*IF} 301210503Ssyrinx eval echo \${${prefix}${_if}${suffix}-${_default}} 302210503Ssyrinx} 303 304# _ifconfig_getargs if [af] 305# Prints the arguments for the supplied interface to stdout. 306# Returns 1 if empty. In general, ifconfig_getargs should be used 307# outside this file. 308_ifconfig_getargs() 309{ 310 local _ifn _af 311 _ifn=$1 312 _af=${2+_$2} 313 314 if [ -z "$_ifn" ]; then 315 return 1 316 fi 317 318 get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT" 319} 320 321# ifconfig_getargs if [af] 322# Takes the result from _ifconfig_getargs and removes pseudo 323# args such as DHCP and WPA. 324ifconfig_getargs() 325{ 326 local _tmpargs _arg _args _vnet 327 _tmpargs=`_ifconfig_getargs $1 $2` 328 if [ $? -eq 1 ]; then 329 return 1 330 fi 331 _args= 332 _vnet=0 333 334 for _arg in $_tmpargs; do 335 case $_arg:$_vnet in 336 [Dd][Hh][Cc][Pp]:0) ;; 337 [Nn][Oo][Aa][Uu][Tt][Oo]:0) ;; 338 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;; 339 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;; 340 [Ww][Pp][Aa]:0) ;; 341 [Hh][Oo][Ss][Tt][Aa][Pp]:0) ;; 342 vnet:0) _vnet=1 ;; 343 *:1) _vnet=0 ;; 344 *:0) 345 _args="$_args $_arg" 346 ;; 347 esac 348 done 349 350 echo $_args 351} 352 353# autoif 354# Returns 0 if the interface should be automatically configured at 355# boot time and 1 otherwise. 356autoif() 357{ 358 local _tmpargs _arg 359 _tmpargs=`_ifconfig_getargs $1` 360 361 for _arg in $_tmpargs; do 362 case $_arg in 363 [Nn][Oo][Aa][Uu][Tt][Oo]) 364 return 1 365 ;; 366 esac 367 done 368 369 return 0 370} 371 372# dhcpif if 373# Returns 0 if the interface is a DHCP interface and 1 otherwise. 374dhcpif() 375{ 376 local _tmpargs _arg 377 _tmpargs=`_ifconfig_getargs $1` 378 379 case $1 in 380 lo[0-9]*|\ 381 stf[0-9]*|\ 382 faith[0-9]*|\ 383 lp[0-9]*|\ 384 sl[0-9]*) 385 return 1 386 ;; 387 esac 388 if noafif $1; then 389 return 1 390 fi 391 392 for _arg in $_tmpargs; do 393 case $_arg in 394 [Dd][Hh][Cc][Pp]) 395 return 0 396 ;; 397 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 398 return 0 399 ;; 400 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 401 return 0 402 ;; 403 esac 404 done 405 406 return 1 407} 408 409# syncdhcpif 410# Returns 0 if the interface should be configured synchronously and 411# 1 otherwise. 412syncdhcpif() 413{ 414 local _tmpargs _arg 415 _tmpargs=`_ifconfig_getargs $1` 416 417 if noafif $1; then 418 return 1 419 fi 420 421 for _arg in $_tmpargs; do 422 case $_arg in 423 [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 424 return 1 425 ;; 426 [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 427 return 0 428 ;; 429 esac 430 done 431 432 checkyesno synchronous_dhclient 433} 434 435# wpaif if 436# Returns 0 if the interface is a WPA interface and 1 otherwise. 437wpaif() 438{ 439 local _tmpargs _arg 440 _tmpargs=`_ifconfig_getargs $1` 441 442 for _arg in $_tmpargs; do 443 case $_arg in 444 [Ww][Pp][Aa]) 445 return 0 446 ;; 447 esac 448 done 449 450 return 1 451} 452 453# hostapif if 454# Returns 0 if the interface is a HOSTAP interface and 1 otherwise. 455hostapif() 456{ 457 local _tmpargs _arg 458 _tmpargs=`_ifconfig_getargs $1` 459 460 for _arg in $_tmpargs; do 461 case $_arg in 462 [Hh][Oo][Ss][Tt][Aa][Pp]) 463 return 0 464 ;; 465 esac 466 done 467 468 return 1 469} 470 471# vnetif if 472# Returns 0 and echo jail if "vnet" keyword is specified on the 473# interface, and 1 otherwise. 474vnetif() 475{ 476 local _tmpargs _arg _vnet 477 _tmpargs=`_ifconfig_getargs $1` 478 479 _vnet=0 480 for _arg in $_tmpargs; do 481 case $_arg:$_vnet in 482 vnet:0) _vnet=1 ;; 483 *:1) echo $_arg; return 0 ;; 484 esac 485 done 486 487 return 1 488} 489 490# afexists af 491# Returns 0 if the address family is enabled in the kernel 492# 1 otherwise. 493afexists() 494{ 495 local _af 496 _af=$1 497 498 case ${_af} in 499 inet|inet6) 500 check_kern_features ${_af} 501 ;; 502 ipx) 503 ${SYSCTL_N} net.ipx > /dev/null 2>&1 504 ;; 505 atm) 506 if [ -x /sbin/atmconfig ]; then 507 /sbin/atmconfig diag list > /dev/null 2>&1 508 else 509 return 1 510 fi 511 ;; 512 link|ether) 513 return 0 514 ;; 515 *) 516 err 1 "afexists(): Unsupported address family: $_af" 517 ;; 518 esac 519} 520 521# noafif if 522# Returns 0 if the interface has no af configuration and 1 otherwise. 523noafif() 524{ 525 local _if 526 _if=$1 527 528 case $_if in 529 pflog[0-9]*|\ 530 pfsync[0-9]*|\ 531 usbus[0-9]*|\ 532 an[0-9]*|\ 533 ath[0-9]*|\ 534 ipw[0-9]*|\ 535 ipfw[0-9]*|\ 536 iwi[0-9]*|\ 537 iwn[0-9]*|\ 538 ral[0-9]*|\ 539 wi[0-9]*|\ 540 wl[0-9]*|\ 541 wpi[0-9]*) 542 return 0 543 ;; 544 esac 545 546 return 1 547} 548 549# ipv6if if 550# Returns 0 if the interface should be configured for IPv6 and 551# 1 otherwise. 552ipv6if() 553{ 554 local _if _tmpargs i 555 _if=$1 556 557 if ! afexists inet6; then 558 return 1 559 fi 560 561 # lo0 is always IPv6-enabled 562 case $_if in 563 lo0) 564 return 0 565 ;; 566 esac 567 568 case "${ipv6_network_interfaces}" in 569 $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo]) 570 # True if $ifconfig_IF_ipv6 is defined. 571 _tmpargs=`_ifconfig_getargs $_if ipv6` 572 if [ -n "${_tmpargs}" ]; then 573 return 0 574 fi 575 576 # True if $ipv6_prefix_IF is defined. 577 _tmpargs=`get_if_var $_if ipv6_prefix_IF` 578 if [ -n "${_tmpargs}" ]; then 579 return 0 580 fi 581 582 # backward compatibility: True if $ipv6_ifconfig_IF is defined. 583 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 584 if [ -n "${_tmpargs}" ]; then 585 return 0 586 fi 587 ;; 588 esac 589 590 return 1 591} 592 593# ipv6_autoconfif if 594# Returns 0 if the interface should be configured for IPv6 with 595# Stateless Address Configuration; 1 otherwise. 596ipv6_autoconfif() 597{ 598 local _if _tmpargs _arg 599 _if=$1 600 601 case $_if in 602 lo[0-9]*|\ 603 stf[0-9]*|\ 604 faith[0-9]*|\ 605 lp[0-9]*|\ 606 sl[0-9]*) 607 return 1 608 ;; 609 esac 610 if noafif $_if; then 611 return 1 612 fi 613 if ! ipv6if $_if; then 614 return 1 615 fi 616 if checkyesno ipv6_gateway_enable; then 617 return 1 618 fi 619 _tmpargs=`get_if_var $_if ipv6_prefix_IF` 620 if [ -n "${_tmpargs}" ]; then 621 return 1 622 fi 623 # backward compatibility: $ipv6_enable 624 case $ipv6_enable in 625 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 626 if checkyesno ipv6_gateway_enable; then 627 return 1 628 fi 629 case $1 in 630 bridge[0-9]*) 631 # No accept_rtadv by default on if_bridge(4) 632 # to avoid a conflict with the member 633 # interfaces. 634 return 1 635 ;; 636 *) 637 return 0 638 ;; 639 esac 640 ;; 641 esac 642 643 _tmpargs=`_ifconfig_getargs $_if ipv6` 644 for _arg in $_tmpargs; do 645 case $_arg in 646 accept_rtadv) 647 return 0 648 ;; 649 esac 650 done 651 652 # backward compatibility: $ipv6_ifconfig_IF 653 _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 654 for _arg in $_tmpargs; do 655 case $_arg in 656 accept_rtadv) 657 return 0 658 ;; 659 esac 660 done 661 662 return 1 663} 664 665# ifexists if 666# Returns 0 if the interface exists and 1 otherwise. 667ifexists() 668{ 669 [ -z "$1" ] && return 1 670 ${IFCONFIG_CMD} -n $1 > /dev/null 2>&1 671} 672 673# ipv4_up if 674# add IPv4 addresses to the interface $if 675ipv4_up() 676{ 677 local _if _ret 678 _if=$1 679 _ret=1 680 681 # Add 127.0.0.1/8 to lo0 unless otherwise specified. 682 if [ "${_if}" = "lo0" ]; then 683 ifconfig_args=`get_if_var ${_if} ifconfig_IF` 684 if [ -z "${ifconfig_args}" ]; then 685 ${IFCONFIG_CMD} ${_if} inet 127.0.0.1/8 alias 686 fi 687 fi 688 ifalias ${_if} inet alias && _ret=0 689 690 return $_ret 691} 692 693# ipv6_up if 694# add IPv6 addresses to the interface $if 695ipv6_up() 696{ 697 local _if _ret 698 _if=$1 699 _ret=1 700 701 if ! ipv6if $_if; then 702 return 0 703 fi 704 705 ifalias ${_if} inet6 alias && _ret=0 706 ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0 707 ipv6_accept_rtadv_up ${_if} && _ret=0 708 709 return $_ret 710} 711 712# ipv4_down if 713# remove IPv4 addresses from the interface $if 714ipv4_down() 715{ 716 local _if _ifs _ret inetList oldifs _inet 717 _if=$1 718 _ifs="^" 719 _ret=1 720 721 ifalias ${_if} inet -alias && _ret=0 722 723 inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet ' | tr "\n\t" "$_ifs"`" 724 725 oldifs="$IFS" 726 IFS="$_ifs" 727 for _inet in $inetList ; do 728 # get rid of extraneous line 729 case $_inet in 730 inet\ *) ;; 731 *) continue ;; 732 esac 733 734 _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 735 736 IFS="$oldifs" 737 ${IFCONFIG_CMD} ${_if} ${_inet} delete 738 IFS="$_ifs" 739 _ret=0 740 done 741 IFS="$oldifs" 742 743 return $_ret 744} 745 746# ipv6_down if 747# remove IPv6 addresses from the interface $if 748ipv6_down() 749{ 750 local _if _ifs _ret inetList oldifs _inet6 751 _if=$1 752 _ifs="^" 753 _ret=1 754 755 if ! ipv6if $_if; then 756 return 0 757 fi 758 759 ipv6_accept_rtadv_down ${_if} && _ret=0 760 ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0 761 ifalias ${_if} inet6 -alias && _ret=0 762 763 inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet6 ' | tr "\n\t" "$_ifs"`" 764 765 oldifs="$IFS" 766 IFS="$_ifs" 767 for _inet6 in $inetList ; do 768 # get rid of extraneous line 769 case $_inet6 in 770 inet6\ *) ;; 771 *) continue ;; 772 esac 773 774 _inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'` 775 776 IFS="$oldifs" 777 ${IFCONFIG_CMD} ${_if} ${_inet6} -alias 778 IFS="$_ifs" 779 _ret=0 780 done 781 IFS="$oldifs" 782 783 return $_ret 784} 785 786# ifalias if af action 787# Configure or remove aliases for network interface $if. 788# It returns 0 if at least one alias was configured or 789# removed, or 1 if there were none. 790# 791ifalias() 792{ 793 local _ret 794 _ret=1 795 796 afexists $2 || return $_ret 797 798 case "$2" in 799 inet|inet6|link|ether) 800 ifalias_af_common $1 $2 $3 && _ret=0 801 ;; 802 esac 803 804 return $_ret 805} 806 807# ifalias_expand_addr af action addr 808# Expand address range ("N-M") specification in addr. 809# "addr" must not include an address-family keyword. 810# The results will include an address-family keyword. 811# 812ifalias_expand_addr() 813{ 814 local _af _action 815 816 _af=$1 817 _action=$2 818 shift 2 819 820 afexists $_af || return 821 ifalias_expand_addr_$_af $_action $* 822} 823 824# ifalias_expand_addr_inet action addr 825# Helper function for ifalias_expand_addr(). Handles IPv4. 826# 827ifalias_expand_addr_inet() 828{ 829 local _action _arg _cidr _cidr_addr _exargs 830 local _ipaddr _plen _range _iphead _iptail _iplow _iphigh _ipcount 831 local _retstr _c 832 _action=$1 833 _arg=$2 834 shift 2 835 _exargs=$* 836 _retstr= 837 838 case $_action:$_arg:$_exargs in 839 *:*--*) return ;; # invalid 840 tmp:*[0-9]-[0-9]*:*) # to be expanded 841 _action="alias" 842 ;; 843 *:*[0-9]-[0-9]*:*) # to be expanded 844 ;; 845 tmp:*:*netmask*) # already expanded w/ netmask option 846 echo ${_arg%/[0-9]*} $_exargs && return 847 ;; 848 tmp:*:*) # already expanded w/o netmask option 849 echo $_arg $_exargs && return 850 ;; 851 *:*:*netmask*) # already expanded w/ netmask option 852 echo inet ${_arg%/[0-9]*} $_exargs && return 853 ;; 854 *:*:*) # already expanded w/o netmask option 855 echo inet $_arg $_exargs && return 856 ;; 857 esac 858 859 for _cidr in $_arg; do 860 _ipaddr=${_cidr%%/*} 861 _plen=${_cidr##*/} 862 # When subnet prefix length is not specified, use /32. 863 case $_plen in 864 $_ipaddr) _plen=32 ;; # "/" character not found 865 esac 866 867 OIFS=$IFS 868 IFS=. set -- $_ipaddr 869 _range= 870 _iphead= 871 _iptail= 872 for _c in $@; do 873 case $_range:$_c in 874 :[0-9]*-[0-9]*) 875 _range=$_c 876 ;; 877 :*) 878 _iphead="${_iphead}${_iphead:+.}${_c}" 879 ;; 880 *:*) 881 _iptail="${_iptail}${_iptail:+.}${_c}" 882 ;; 883 esac 884 done 885 IFS=$OIFS 886 _iplow=${_range%-*} 887 _iphigh=${_range#*-} 888 889 # clear netmask when removing aliases 890 if [ "$_action" = "-alias" ]; then 891 _plen="" 892 fi 893 894 _ipcount=$_iplow 895 while [ "$_ipcount" -le "$_iphigh" ]; do 896 _retstr="${_retstr} ${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail}${_plen:+/}${_plen}" 897 if [ $_ipcount -gt $(($_iplow + $netif_ipexpand_max)) ]; then 898 warn "Range specification is too large (${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_iphigh}${_iptail:+.}${_iptail}). ${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail} was processed. Increase \$netif_ipexpand_max in rc.conf." 899 break 900 else 901 _ipcount=$(($_ipcount + 1)) 902 fi 903 # Forcibly set /32 for remaining aliases. 904 _plen=32 905 done 906 done 907 908 for _c in $_retstr; do 909 ifalias_expand_addr_inet $_action $_c $_exargs 910 done 911} 912 913# ifalias_expand_addr_inet6 action addr 914# Helper function for ifalias_expand_addr(). Handles IPv6. 915# 916ifalias_expand_addr_inet6() 917{ 918 local _action _arg _cidr _cidr_addr _exargs 919 local _ipaddr _plen _ipleft _ipright _iplow _iphigh _ipcount 920 local _ipv4part 921 local _retstr _c 922 _action=$1 923 _arg=$2 924 shift 2 925 _exargs=$* 926 _retstr= 927 928 case $_action:$_arg:$_exargs in 929 *:*--*:*) return ;; # invalid 930 tmp:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*)# to be expanded 931 _action="alias" 932 ;; 933 *:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*) # to be expanded 934 ;; 935 tmp:*:*prefixlen*) # already expanded w/ prefixlen option 936 echo ${_arg%/[0-9]*} $_exargs && return 937 ;; 938 tmp:*:*) # already expanded w/o prefixlen option 939 echo $_arg $_exargs && return 940 ;; 941 *:*:*prefixlen*) # already expanded w/ prefixlen option 942 echo inet6 ${_arg%/[0-9]*} $_exargs && return 943 ;; 944 *:*:*) # already expanded w/o prefixlen option 945 echo inet6 $_arg $_exargs && return 946 ;; 947 esac 948 949 for _cidr in $_arg; do 950 _ipaddr="${_cidr%%/*}" 951 _plen="${_cidr##*/}" 952 953 case $_action:$_ipaddr:$_cidr in 954 -alias:*:*) unset _plen ;; 955 *:$_cidr:$_ipaddr) unset _plen ;; 956 esac 957 958 if [ "${_ipaddr%:*.*.*.*}" = "$_ipaddr" ]; then 959 # Handle !v4mapped && !v4compat addresses. 960 961 # The default prefix length is 64. 962 case $_ipaddr:$_cidr in 963 $_cidr:$_ipaddr) _plen="64" ;; 964 esac 965 _ipleft=${_ipaddr%-*} 966 _ipright=${_ipaddr#*-} 967 _iplow=${_ipleft##*:} 968 _iphigh=${_ipright%%:*} 969 _ipleft=${_ipleft%:*} 970 _ipright=${_ipright#*:} 971 972 if [ "$_iphigh" = "$_ipright" ]; then 973 unset _ipright 974 else 975 _ipright=:$_ipright 976 fi 977 978 if [ -n "$_iplow" -a -n "$_iphigh" ]; then 979 _iplow=$((0x$_iplow)) 980 _iphigh=$((0x$_iphigh)) 981 _ipcount=$_iplow 982 while [ $_ipcount -le $_iphigh ]; do 983 _r=`printf "%s:%04x%s%s" \ 984 $_ipleft $_ipcount $_ipright \ 985 ${_plen:+/}$_plen` 986 _retstr="$_retstr $_r" 987 if [ $_ipcount -gt $(($_iplow + $netif_ipexpand_max)) ] 988 then 989 warn "Range specification is too large $(printf '(%s:%x%s-%s:%x%s)' "$_ipleft" "$_iplow" "$_ipright" "$_ipleft" "$_iphigh" "$_ipright"). $(printf '%s:%x%s-%s:%x%s' "$_ipleft" "$_iplow" "$_ipright" "$_ipleft" "$_ipcount" "$_ipright") was processed. Increase \$netif_ipexpand_max in rc.conf." 990 break 991 else 992 _ipcount=$(($_ipcount + 1)) 993 fi 994 done 995 else 996 _retstr="${_ipaddr}${_plen:+/}${_plen}" 997 fi 998 999 for _c in $_retstr; do 1000 ifalias_expand_addr_inet6 $_action $_c $_exargs 1001 done 1002 else 1003 # v4mapped/v4compat should handle as an IPv4 alias 1004 _ipv4part=${_ipaddr##*:} 1005 1006 # Adjust prefix length if any. If not, set the 1007 # default prefix length as 32. 1008 case $_ipaddr:$_cidr in 1009 $_cidr:$_ipaddr) _plen=32 ;; 1010 *) _plen=$(($_plen - 96)) ;; 1011 esac 1012 1013 _retstr=`ifalias_expand_addr_inet \ 1014 tmp ${_ipv4part}${_plen:+/}${_plen}` 1015 for _c in $_retstr; do 1016 ifalias_expand_addr_inet $_action $_c $_exargs 1017 done 1018 fi 1019 done 1020} 1021 1022# ifalias_af_common_handler if af action args 1023# Helper function for ifalias_af_common(). 1024# 1025ifalias_af_common_handler() 1026{ 1027 local _ret _if _af _action _args _c _tmpargs 1028 1029 _ret=1 1030 _if=$1 1031 _af=$2 1032 _action=$3 1033 shift 3 1034 _args=$* 1035 1036 case $_args in 1037 ${_af}\ *) ;; 1038 *) return ;; 1039 esac 1040 1041 # link(ether) does not support address removal. 1042 case $_af:$_action in 1043 link:-alias|ether:-alias) return ;; 1044 esac 1045 1046 _tmpargs= 1047 for _c in $_args; do 1048 case $_c in 1049 ${_af}) 1050 case $_tmpargs in 1051 ${_af}\ *[0-9a-fA-F]-*) 1052 ifalias_af_common_handler $_if $_af $_action \ 1053 `ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }` 1054 ;; 1055 ${_af}\ *) 1056 ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 1057 ;; 1058 esac 1059 _tmpargs=$_af 1060 ;; 1061 *) 1062 _tmpargs="$_tmpargs $_c" 1063 ;; 1064 esac 1065 done 1066 # Process the last component if any. 1067 if [ -n "$_tmpargs}" ]; then 1068 case $_tmpargs in 1069 ${_af}\ *[0-9a-fA-F]-*) 1070 ifalias_af_common_handler $_if $_af $_action \ 1071 `ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }` 1072 ;; 1073 ${_af}\ *) 1074 ${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0 1075 ;; 1076 esac 1077 fi 1078 1079 return $_ret 1080} 1081 1082# ifalias_af_common if af action 1083# Helper function for ifalias(). 1084# 1085ifalias_af_common() 1086{ 1087 local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf 1088 local _vif _punct=".-/+" 1089 1090 _ret=1 1091 _aliasn= 1092 _if=$1 1093 _af=$2 1094 _action=$3 1095 1096 # Normalize $_if before using it in a pattern to list_vars() 1097 ltr "$_if" "$_punct" "_" _vif 1098 1099 # ifconfig_IF_aliasN which starts with $_af 1100 for alias in `list_vars ifconfig_${_vif}_alias[0-9]\* | 1101 sort_lite -nk1.$((9+${#_vif}+7))` 1102 do 1103 eval ifconfig_args=\"\$$alias\" 1104 _iaf= 1105 case $ifconfig_args in 1106 inet\ *) _iaf=inet ;; 1107 inet6\ *) _iaf=inet6 ;; 1108 ipx\ *) _iaf=ipx ;; 1109 link\ *) _iaf=link ;; 1110 ether\ *) _iaf=ether ;; 1111 esac 1112 1113 case ${_af}:${_action}:${_iaf}:"${ifconfig_args}" in 1114 ${_af}:*:${_af}:*) 1115 _aliasn="$_aliasn $ifconfig_args" 1116 ;; 1117 ${_af}:*:"":"") 1118 break 1119 ;; 1120 inet:alias:"":*) 1121 _aliasn="$_aliasn inet $ifconfig_args" 1122 warn "\$${alias} needs leading" \ 1123 "\"inet\" keyword for an IPv4 address." 1124 esac 1125 done 1126 1127 # backward compatibility: ipv6_ifconfig_IF_aliasN. 1128 case $_af in 1129 inet6) 1130 for alias in `list_vars ipv6_ifconfig_${_vif}_alias[0-9]\* | 1131 sort_lite -nk1.$((14+${#_vif}+7))` 1132 do 1133 eval ifconfig_args=\"\$$alias\" 1134 case ${_action}:"${ifconfig_args}" in 1135 *:"") 1136 break 1137 ;; 1138 alias:*) 1139 _aliasn="${_aliasn} inet6 ${ifconfig_args}" 1140 warn "\$${alias} is obsolete. " \ 1141 "Use ifconfig_${_vif}_aliasN instead." 1142 ;; 1143 esac 1144 done 1145 esac 1146 1147 # backward compatibility: ipv4_addrs_IF. 1148 for _tmpargs in `get_if_var $_if ipv4_addrs_IF`; do 1149 _aliasn="$_aliasn inet $_tmpargs" 1150 done 1151 1152 # Handle ifconfig_IF_aliases, ifconfig_IF_aliasN, and the others. 1153 _tmpargs= 1154 for _c in `get_if_var $_if ifconfig_IF_aliases` $_aliasn; do 1155 case $_c in 1156 inet|inet6|ipx|link|ether) 1157 case $_tmpargs in 1158 ${_af}\ *) 1159 eval ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0 1160 ;; 1161 esac 1162 _tmpargs=$_c 1163 ;; 1164 *) 1165 _tmpargs="$_tmpargs $_c" 1166 esac 1167 done 1168 # Process the last component 1169 case $_tmpargs in 1170 ${_af}\ *) 1171 ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0 1172 ;; 1173 esac 1174 1175 return $_ret 1176} 1177 1178# ipv6_prefix_hostid_addr_common if action 1179# Add or remove IPv6 prefix + hostid addr on the interface $if 1180# 1181ipv6_prefix_hostid_addr_common() 1182{ 1183 local _if _action prefix j 1184 _if=$1 1185 _action=$2 1186 prefix=`get_if_var ${_if} ipv6_prefix_IF` 1187 1188 if [ -n "${prefix}" ]; then 1189 for j in ${prefix}; do 1190 # The default prefixlen is 64. 1191 plen=${j#*/} 1192 case $j:$plen in 1193 $plen:$j) plen=64 ;; 1194 *) j=${j%/*} ;; 1195 esac 1196 1197 # Normalize the last part by removing ":" 1198 j=${j%::*} 1199 j=${j%:} 1200 ${IFCONFIG_CMD} ${_if} inet6 $j:: \ 1201 prefixlen $plen eui64 ${_action} 1202 1203 # if I am a router, add subnet router 1204 # anycast address (RFC 2373). 1205 if checkyesno ipv6_gateway_enable; then 1206 ${IFCONFIG_CMD} ${_if} inet6 $j:: \ 1207 prefixlen $plen ${_action} anycast 1208 fi 1209 done 1210 fi 1211} 1212 1213# ipv6_accept_rtadv_up if 1214# Enable accepting Router Advertisement and send Router 1215# Solicitation message 1216ipv6_accept_rtadv_up() 1217{ 1218 if ipv6_autoconfif $1; then 1219 ${IFCONFIG_CMD} $1 inet6 accept_rtadv up 1220 if ! checkyesno rtsold_enable; then 1221 rtsol ${rtsol_flags} $1 1222 fi 1223 fi 1224} 1225 1226# ipv6_accept_rtadv_down if 1227# Disable accepting Router Advertisement 1228ipv6_accept_rtadv_down() 1229{ 1230 if ipv6_autoconfif $1; then 1231 ${IFCONFIG_CMD} $1 inet6 -accept_rtadv 1232 fi 1233} 1234 1235# ifscript_up if 1236# Evaluate a startup script for the $if interface. 1237# It returns 0 if a script was found and processed or 1238# 1 if no script was found. 1239# 1240ifscript_up() 1241{ 1242 if [ -r /etc/start_if.$1 ]; then 1243 . /etc/start_if.$1 1244 return 0 1245 else 1246 return 1 1247 fi 1248} 1249 1250# ifscript_down if 1251# Evaluate a shutdown script for the $if interface. 1252# It returns 0 if a script was found and processed or 1253# 1 if no script was found. 1254# 1255ifscript_down() 1256{ 1257 if [ -r /etc/stop_if.$1 ]; then 1258 . /etc/stop_if.$1 1259 return 0 1260 else 1261 return 1 1262 fi 1263} 1264 1265# clone_up 1266# Create cloneable interfaces. 1267# 1268clone_up() 1269{ 1270 local _list ifn ifopt _iflist _n tmpargs 1271 _list= 1272 _iflist=$* 1273 1274 # create_args_IF 1275 for ifn in ${cloned_interfaces}; do 1276 # Parse ifn:ifopt. 1277 OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS 1278 case $_iflist in 1279 ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;; 1280 *) continue ;; 1281 esac 1282 case $ifn in 1283 epair[0-9]*) 1284 # epair(4) uses epair[0-9] for creation and 1285 # epair[0-9][ab] for configuration. 1286 # 1287 # Skip if ${ifn}a or ${ifn}b already exist. 1288 if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then 1289 continue 1290 elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then 1291 continue 1292 fi 1293 ${IFCONFIG_CMD} ${ifn} create \ 1294 `get_if_var ${ifn} create_args_IF` 1295 if [ $? -eq 0 ]; then 1296 _list="$_list ${ifn}a ${ifn}b" 1297 fi 1298 ;; 1299 *) 1300 # Skip if ${ifn} already exists. 1301 if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then 1302 continue 1303 fi 1304 ${IFCONFIG_CMD} ${ifn} create \ 1305 `get_if_var ${ifn} create_args_IF` 1306 if [ $? -eq 0 ]; then 1307 _list="$_list $ifn" 1308 fi 1309 esac 1310 done 1311 if [ -n "$gif_interfaces" ]; then 1312 warn "\$gif_interfaces is obsolete. Use \$cloned_interfaces instead." 1313 fi 1314 for ifn in ${gif_interfaces}; do 1315 # Parse ifn:ifopt. 1316 OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS 1317 case $_iflist in 1318 ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;; 1319 *) continue ;; 1320 esac 1321 # Skip if ifn already exists. 1322 if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then 1323 continue 1324 fi 1325 case $ifn in 1326 gif[0-9]*) 1327 ${IFCONFIG_CMD} $ifn create 1328 ;; 1329 *) 1330 _n=$(${IFCONFIG_CMD} gif create) 1331 ${IFCONFIG_CMD} $_n name $ifn 1332 ;; 1333 esac 1334 if [ $? -eq 0 ]; then 1335 _list="$_list $ifn" 1336 fi 1337 tmpargs=$(get_if_var $ifn gifconfig_IF) 1338 eval ifconfig_${ifn}=\"tunnel \$tmpargs\" 1339 done 1340 if [ -n "${_list# }" ]; then 1341 echo "Created clone interfaces: ${_list# }." 1342 fi 1343 debug "Cloned: ${_list# }" 1344} 1345 1346# clone_down 1347# Destroy cloned interfaces. Destroyed interfaces are echoed to 1348# standard output. 1349# 1350clone_down() 1351{ 1352 local _list ifn _difn ifopt _iflist _sticky 1353 _list= 1354 _iflist=$* 1355 1356 : ${cloned_interfaces_sticky:=NO} 1357 if checkyesno cloned_interfaces_sticky; then 1358 _sticky=1 1359 else 1360 _sticky=0 1361 fi 1362 for ifn in ${cloned_interfaces} ${gif_interfaces}; do 1363 # Parse ifn:ifopt. 1364 OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS 1365 case $ifopt:$_sticky in 1366 sticky:*) continue ;; # :sticky => not destroy 1367 nosticky:*) ;; # :nosticky => destroy 1368 *:1) continue ;; # global sticky knob == 1 1369 esac 1370 case $_iflist in 1371 ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;; 1372 *) continue ;; 1373 esac 1374 case $ifn in 1375 epair[0-9]*) 1376 # Note: epair(4) uses epair[0-9] for removal and 1377 # epair[0-9][ab] for configuration. 1378 # 1379 # Skip if both of ${ifn}a and ${ifn}b do not exist. 1380 if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then 1381 _difn=${ifn}a 1382 elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then 1383 _difn=${ifn}b 1384 else 1385 continue 1386 fi 1387 ${IFCONFIG_CMD} -n $_difn destroy 1388 if [ $? -eq 0 ]; then 1389 _list="$_list ${ifn}a ${ifn}b" 1390 fi 1391 ;; 1392 *) 1393 # Skip if ifn does not exist. 1394 if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then 1395 continue 1396 fi 1397 ${IFCONFIG_CMD} -n ${ifn} destroy 1398 if [ $? -eq 0 ]; then 1399 _list="$_list $ifn" 1400 fi 1401 ;; 1402 esac 1403 done 1404 if [ -n "${_list# }" ]; then 1405 echo "Destroyed clone interfaces: ${_list# }." 1406 fi 1407 debug "Destroyed clones: ${_list# }" 1408} 1409 1410# childif_create 1411# Create and configure child interfaces. Return 0 if child 1412# interfaces are created. 1413# 1414childif_create() 1415{ 1416 local cfg child child_vlans child_wlans create_args debug_flags ifn i 1417 cfg=1 1418 ifn=$1 1419 1420 # Create wireless interfaces 1421 child_wlans=`get_if_var $ifn wlans_IF` 1422 1423 for child in ${child_wlans}; do 1424 create_args="wlandev $ifn `get_if_var $child create_args_IF`" 1425 debug_flags="`get_if_var $child wlandebug_IF`" 1426 1427 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then 1428 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1429 if [ -n "${debug_flags}" ]; then 1430 wlandebug -i $child ${debug_flags} 1431 fi 1432 else 1433 i=`${IFCONFIG_CMD} wlan create ${create_args}` 1434 if [ -n "${debug_flags}" ]; then 1435 wlandebug -i $i ${debug_flags} 1436 fi 1437 ${IFCONFIG_CMD} $i name $child && cfg=0 1438 fi 1439 if autoif $child; then 1440 ifn_start $child 1441 fi 1442 done 1443 1444 # Create vlan interfaces 1445 child_vlans=`get_if_var $ifn vlans_IF` 1446 1447 if [ -n "${child_vlans}" ]; then 1448 load_kld if_vlan 1449 fi 1450 1451 for child in ${child_vlans}; do 1452 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1453 child="${ifn}.${child}" 1454 create_args=`get_if_var $child create_args_IF` 1455 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1456 else 1457 create_args="vlandev $ifn `get_if_var $child create_args_IF`" 1458 if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then 1459 ${IFCONFIG_CMD} $child create ${create_args} && cfg=0 1460 else 1461 i=`${IFCONFIG_CMD} vlan create ${create_args}` 1462 ${IFCONFIG_CMD} $i name $child && cfg=0 1463 fi 1464 fi 1465 if autoif $child; then 1466 ifn_start $child 1467 fi 1468 done 1469 1470 return ${cfg} 1471} 1472 1473# childif_destroy 1474# Destroy child interfaces. 1475# 1476childif_destroy() 1477{ 1478 local cfg child child_vlans child_wlans ifn 1479 cfg=1 1480 1481 child_wlans=`get_if_var $ifn wlans_IF` 1482 for child in ${child_wlans}; do 1483 if ! ifexists $child; then 1484 continue 1485 fi 1486 ${IFCONFIG_CMD} -n $child destroy && cfg=0 1487 done 1488 1489 child_vlans=`get_if_var $ifn vlans_IF` 1490 for child in ${child_vlans}; do 1491 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1492 child="${ifn}.${child}" 1493 fi 1494 if ! ifexists $child; then 1495 continue 1496 fi 1497 ${IFCONFIG_CMD} -n $child destroy && cfg=0 1498 done 1499 1500 return ${cfg} 1501} 1502 1503# ng_mkpeer 1504# Create netgraph nodes. 1505# 1506ng_mkpeer() 1507{ 1508 ngctl -f - 2> /dev/null <<EOF 1509mkpeer $* 1510msg dummy nodeinfo 1511EOF 1512} 1513 1514# ng_create_one 1515# Create netgraph nodes. 1516# 1517ng_create_one() 1518{ 1519 local t 1520 1521 ng_mkpeer $* | while read line; do 1522 t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'` 1523 if [ -n "${t}" ]; then 1524 echo ${t} 1525 return 1526 fi 1527 done 1528} 1529 1530# ng_fec_create ifn 1531# Configure Fast EtherChannel for interface $ifn. Returns 0 if 1532# FEC arguments were found and configured; returns !0 otherwise. 1533ng_fec_create() 1534{ 1535 local req_iface iface bogus 1536 req_iface="$1" 1537 1538 ngctl shutdown ${req_iface}: > /dev/null 2>&1 1539 1540 bogus="" 1541 while true; do 1542 iface=`ng_create_one fec dummy fec` 1543 if [ -z "${iface}" ]; then 1544 exit 2 1545 fi 1546 if [ "${iface}" = "${req_iface}" ]; then 1547 break 1548 fi 1549 bogus="${bogus} ${iface}" 1550 done 1551 1552 for iface in ${bogus}; do 1553 ngctl shutdown ${iface}: 1554 done 1555} 1556 1557# fec_up 1558# Create Fast EtherChannel interfaces. 1559fec_up() 1560{ 1561 local i j 1562 1563 for i in ${fec_interfaces}; do 1564 ng_fec_create $i 1565 for j in `get_if_var $i fecconfig_IF`; do 1566 case ${j} in 1567 '') 1568 continue 1569 ;; 1570 *) 1571 ngctl msg ${i}: add_iface "\"${j}\"" 1572 ;; 1573 esac 1574 done 1575 done 1576} 1577 1578# ipx_up ifn 1579# Configure any IPX addresses for interface $ifn. Returns 0 if 1580# IPX arguments were found and configured; returns 1 otherwise. 1581# 1582ipx_up() 1583{ 1584 local ifn 1585 ifn="$1" 1586 1587 # ifconfig_IF_ipx 1588 ifconfig_args=`_ifconfig_getargs $ifn ipx` 1589 if [ -n "${ifconfig_args}" ]; then 1590 ${IFCONFIG_CMD} ${ifn} ${ifconfig_args} 1591 return 0 1592 fi 1593 1594 return 1 1595} 1596 1597# ipx_down ifn 1598# Remove IPX addresses for interface $ifn. Returns 0 if IPX 1599# addresses were found and unconfigured. It returns 1, otherwise. 1600# 1601ipx_down() 1602{ 1603 local _if _ifs _ret ipxList oldifs _ipx 1604 _if=$1 1605 _ifs="^" 1606 _ret=1 1607 ipxList="`${IFCONFIG_CMD} ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`" 1608 oldifs="$IFS" 1609 1610 IFS="$_ifs" 1611 for _ipx in $ipxList ; do 1612 # get rid of extraneous line 1613 [ -z "$_ipx" ] && break 1614 1615 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 1616 1617 IFS="$oldifs" 1618 ${IFCONFIG_CMD} ${_if} ${_ipx} delete 1619 IFS="$_ifs" 1620 _ret=0 1621 done 1622 IFS="$oldifs" 1623 1624 return $_ret 1625} 1626 1627# ifnet_rename [ifname] 1628# Rename interfaces if ifconfig_IF_name is defined. 1629# 1630ifnet_rename() 1631{ 1632 local _if _ifname 1633 1634 # ifconfig_IF_name 1635 for _if in ${*:-$(${IFCONFIG_CMD} -l)}; do 1636 _ifname=`get_if_var $_if ifconfig_IF_name` 1637 if [ ! -z "$_ifname" ]; then 1638 ${IFCONFIG_CMD} $_if name $_ifname 1639 fi 1640 done 1641 1642 return 0 1643} 1644 1645# list_net_interfaces type 1646# List all network interfaces. The type of interface returned 1647# can be controlled by the type argument. The type 1648# argument can be any of the following: 1649# nodhcp - all interfaces, excluding DHCP configured interfaces 1650# dhcp - list only DHCP configured interfaces 1651# noautoconf - all interfaces, excluding IPv6 Stateless 1652# Address Autoconf configured interfaces 1653# autoconf - list only IPv6 Stateless Address Autoconf 1654# configured interfaces 1655# If no argument is specified all network interfaces are output. 1656# Note that the list will include cloned interfaces if applicable. 1657# Cloned interfaces must already exist to have a chance to appear 1658# in the list if ${network_interfaces} is set to `auto'. 1659# 1660list_net_interfaces() 1661{ 1662 local type _tmplist _list _autolist _lo _if 1663 type=$1 1664 1665 # Get a list of ALL the interfaces and make lo0 first if it's there. 1666 # 1667 _tmplist= 1668 case ${network_interfaces} in 1669 [Aa][Uu][Tt][Oo]) 1670 _autolist="`${IFCONFIG_CMD} -l`" 1671 _lo= 1672 for _if in ${_autolist} ; do 1673 if autoif $_if; then 1674 if [ "$_if" = "lo0" ]; then 1675 _lo="lo0 " 1676 else 1677 _tmplist="${_tmplist} ${_if}" 1678 fi 1679 fi 1680 done 1681 _tmplist="${_lo}${_tmplist# }" 1682 ;; 1683 *) 1684 for _if in ${network_interfaces} ${cloned_interfaces}; do 1685 # epair(4) uses epair[0-9] for creation and 1686 # epair[0-9][ab] for configuration. 1687 case $_if in 1688 epair[0-9]*) 1689 _tmplist="$_tmplist ${_if}a ${_if}b" 1690 ;; 1691 *) 1692 _tmplist="$_tmplist $_if" 1693 ;; 1694 esac 1695 done 1696 # 1697 # lo0 is effectively mandatory, so help prevent foot-shooting 1698 # 1699 case "$_tmplist" in 1700 lo0|'lo0 '*|*' lo0'|*' lo0 '*) 1701 # This is fine, do nothing 1702 _tmplist="${_tmplist# }" 1703 ;; 1704 *) 1705 _tmplist="lo0 ${_tmplist# }" 1706 ;; 1707 esac 1708 ;; 1709 esac 1710 1711 _list= 1712 case "$type" in 1713 nodhcp) 1714 for _if in ${_tmplist} ; do 1715 if ! dhcpif $_if && \ 1716 [ -n "`_ifconfig_getargs $_if`" ]; then 1717 _list="${_list# } ${_if}" 1718 fi 1719 done 1720 ;; 1721 dhcp) 1722 for _if in ${_tmplist} ; do 1723 if dhcpif $_if; then 1724 _list="${_list# } ${_if}" 1725 fi 1726 done 1727 ;; 1728 noautoconf) 1729 for _if in ${_tmplist} ; do 1730 if ! ipv6_autoconfif $_if && \ 1731 [ -n "`_ifconfig_getargs $_if ipv6`" ]; then 1732 _list="${_list# } ${_if}" 1733 fi 1734 done 1735 ;; 1736 autoconf) 1737 for _if in ${_tmplist} ; do 1738 if ipv6_autoconfif $_if; then 1739 _list="${_list# } ${_if}" 1740 fi 1741 done 1742 ;; 1743 *) 1744 _list=${_tmplist} 1745 ;; 1746 esac 1747 1748 echo $_list 1749 1750 return 0 1751} 1752 1753# get_default_if -address_family 1754# Get the interface of the default route for the given address family. 1755# The -address_family argument must be suitable passing to route(8). 1756# 1757get_default_if() 1758{ 1759 local routeget oldifs defif line 1760 defif= 1761 oldifs="$IFS" 1762 IFS=" 1763" 1764 for line in `route -n get $1 default 2>/dev/null`; do 1765 case $line in 1766 *interface:*) 1767 defif=${line##*: } 1768 ;; 1769 esac 1770 done 1771 IFS=${oldifs} 1772 1773 echo $defif 1774} 1775 1776# hexdigit arg 1777# Echo decimal number $arg (single digit) in hexadecimal format. 1778hexdigit() 1779{ 1780 printf '%x\n' "$1" 1781} 1782 1783# hexprint arg 1784# Echo decimal number $arg (multiple digits) in hexadecimal format. 1785hexprint() 1786{ 1787 printf '%x\n' "$1" 1788} 1789 1790is_wired_interface() 1791{ 1792 local media 1793 1794 case `${IFCONFIG_CMD} $1 2>/dev/null` in 1795 *media:?Ethernet*) media=Ethernet ;; 1796 esac 1797 1798 test "$media" = "Ethernet" 1799} 1800 1801# network6_getladdr if [flag] 1802# Echo link-local address from $if if any. 1803# If flag is defined, tentative ones will be excluded. 1804network6_getladdr() 1805{ 1806 local _if _flag proto addr rest 1807 _if=$1 1808 _flag=$2 1809 1810 ${IFCONFIG_CMD} $_if 2>/dev/null | while read proto addr rest; do 1811 case "${proto}/${addr}/${_flag}/${rest}" in 1812 inet6/fe80::*//*) 1813 echo ${addr} 1814 ;; 1815 inet6/fe80:://*tentative*) # w/o flag 1816 sleep `${SYSCTL_N} net.inet6.ip6.dad_count` 1817 network6_getladdr $_if $_flags 1818 ;; 1819 inet6/fe80::/*/*tentative*) # w/ flag 1820 echo ${addr} 1821 ;; 1822 *) 1823 continue 1824 ;; 1825 esac 1826 1827 return 1828 done 1829} 1830