network revision 1.64
1#!/bin/sh 2# 3# $NetBSD: network,v 1.64 2014/04/29 09:42:51 uebayasi Exp $ 4# 5 6# PROVIDE: network 7# REQUIRE: ipfilter ipsec mountcritlocal root tty sysctl 8# BEFORE: NETWORKING 9 10$_rc_subr_loaded . /etc/rc.subr 11 12name="network" 13start_cmd="network_start" 14stop_cmd="network_stop" 15 16nl=' 17' # a newline 18 19intmissing() { 20 local int="$1" 21 shift 22 for i 23 do 24 if [ "$int" = "$i" ]; then 25 return 1 26 fi 27 done 28 return 0 29} 30 31network_start() 32{ 33 # set hostname, turn on network 34 # 35 echo "Starting network." 36 37 network_start_hostname 38 network_start_domainname 39 network_start_loopback 40 network_start_ipv6_route 41 network_start_interfaces 42 network_start_aliases 43 network_start_defaultroute 44 network_start_defaultroute6 45 network_start_ipv6_autoconf 46 network_start_local 47} 48 49network_start_hostname() 50{ 51 # If $hostname is set, use it for my Internet name, 52 # otherwise use /etc/myname 53 # 54 if [ -z "$hostname" ] && [ -f /etc/myname ]; then 55 hostname=$(cat /etc/myname) 56 fi 57 if [ -n "$hostname" ]; then 58 echo "Hostname: $hostname" 59 hostname $hostname 60 else 61 # Don't warn about it if we're going to run 62 # DHCP later, as we will probably get the 63 # hostname at that time. 64 # 65 if ! checkyesno dhclient && ! checkyesno dhcpcd && \ 66 [ -z "$(hostname)" ] 67 then 68 warn "\$hostname not set." 69 fi 70 fi 71} 72 73network_start_domainname() 74{ 75 # Check $domainname first, then /etc/defaultdomain, 76 # for NIS/YP domain name 77 # 78 if [ -z "$domainname" ] && [ -f /etc/defaultdomain ]; then 79 domainname=$(cat /etc/defaultdomain) 80 fi 81 if [ -n "$domainname" ]; then 82 echo "NIS domainname: $domainname" 83 domainname $domainname 84 fi 85 86 # Flush all routes just to make sure it is clean 87 if checkyesno flushroutes; then 88 /sbin/route -qn flush 89 fi 90} 91 92network_start_loopback() 93{ 94 # Set the address for the first loopback interface, so that the 95 # auto-route from a newly configured interface's address to lo0 96 # works correctly. 97 # 98 # NOTE: obscure networking problems will occur if lo0 isn't configured. 99 # 100 /sbin/ifconfig lo0 inet 127.0.0.1 101 102 # According to RFC1122, 127.0.0.0/8 must not leave the node. 103 # 104 /sbin/route -q add -inet 127.0.0.0 -netmask 0xff000000 127.0.0.1 -reject 105} 106 107network_start_ipv6_route() 108{ 109 # IPv6 routing setups, and host/router mode selection. 110 # 111 if /sbin/ifconfig lo0 inet6 >/dev/null 2>&1; then 112 # We have IPv6 support in kernel. 113 114 # disallow link-local unicast dest without outgoing scope 115 # identifiers. 116 # 117 /sbin/route -q add -inet6 fe80:: -prefixlen 10 ::1 -reject 118 119 # disallow the use of the RFC3849 documentation address 120 # 121 /sbin/route -q add -inet6 2001:db8:: -prefixlen 32 ::1 -reject 122 123 # IPv6 site-local scoped address prefix (fec0::/10) 124 # has been deprecated by RFC3879. 125 # 126 if [ -n "$ip6sitelocal" ]; then 127 warn "\$ip6sitelocal is no longer valid" 128 fi 129 130 # disallow "internal" addresses to appear on the wire. 131 # 132 /sbin/route -q add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject 133 134 # disallow packets to malicious IPv4 compatible prefix 135 # 136 /sbin/route -q add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject 137 /sbin/route -q add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject 138 /sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject 139 /sbin/route -q add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject 140 141 # disallow packets to malicious 6to4 prefix 142 # 143 /sbin/route -q add -inet6 2002:e000:: -prefixlen 20 ::1 -reject 144 /sbin/route -q add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject 145 /sbin/route -q add -inet6 2002:0000:: -prefixlen 24 ::1 -reject 146 /sbin/route -q add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject 147 148 # Completely disallow packets to IPv4 compatible prefix. 149 # This may conflict with RFC1933 under following circumstances: 150 # (1) An IPv6-only KAME node tries to originate packets to IPv4 151 # compatible destination. The KAME node has no IPv4 152 # compatible support. Under RFC1933, it should transmit 153 # native IPv6 packets toward IPv4 compatible destination, 154 # hoping it would reach a router that forwards the packet 155 # toward auto-tunnel interface. 156 # (2) An IPv6-only node originates a packet to IPv4 compatible 157 # destination. A KAME node is acting as an IPv6 router, and 158 # asked to forward it. 159 # Due to rare use of IPv4 compatible address, and security 160 # issues with it, we disable it by default. 161 # 162 /sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject 163 164 /sbin/sysctl -qw net.inet6.ip6.forwarding=0 165 /sbin/sysctl -qw net.inet6.ip6.accept_rtadv=0 166 167 case $ip6mode in 168 router) 169 echo 'IPv6 mode: router' 170 /sbin/sysctl -qw net.inet6.ip6.forwarding=1 171 172 # disallow unique-local unicast forwarding without 173 # explicit configuration. 174 if ! checkyesno ip6uniquelocal; then 175 /sbin/route -q add -inet6 fc00:: -prefixlen 7 \ 176 ::1 -reject 177 fi 178 ;; 179 180 autohost) 181 echo 'IPv6 mode: autoconfigured host' 182 /sbin/sysctl -qw net.inet6.ip6.accept_rtadv=1 183 ;; 184 185 host) 186 echo 'IPv6 mode: host' 187 ;; 188 189 *) warn "invalid \$ip6mode value "\"$ip6mode\" 190 ;; 191 192 esac 193 fi 194} 195 196network_start_interfaces() 197{ 198 # Configure all of the network interfaces listed in $net_interfaces; 199 # if $auto_ifconfig is YES, grab all interfaces from ifconfig. 200 # In the following, "xxN" stands in for interface names, like "le0". 201 # 202 # For any interfaces that has an $ifconfig_xxN variable 203 # associated, we break it into lines using ';' as a separator, 204 # then process it just like the contents of an /etc/ifconfig.xxN 205 # file. 206 # 207 # For each line from the $ifconfig_xxN variable or the 208 # /etc/ifconfig.xxN file, we ignore comments and blank lines, 209 # treat lines beginning with "!" as commands to execute, treat 210 # "dhcp" as a special case to invoke dhcpcd, and for any other 211 # line we run "ifconfig xxN", using each line of the file as the 212 # arguments for a separate "ifconfig" invocation. 213 # 214 # In order to configure an interface reasonably, you at the very least 215 # need to specify "[addr_family] [hostname]" (e.g "inet my.domain.org"), 216 # and probably a netmask (as in "netmask 0xffffffe0"). You will 217 # frequently need to specify a media type, as in "media UTP", for 218 # interface cards with multiple media connections that do not 219 # autoconfigure. See the ifconfig manual page for details. 220 # 221 # Note that /etc/ifconfig.xxN takes multiple lines. The following 222 # configuration is possible: 223 # inet 10.1.1.1 netmask 0xffffff00 224 # inet 10.1.1.2 netmask 0xffffff00 alias 225 # inet6 2001:db8::1 prefixlen 64 alias 226 # 227 # You can put shell script fragment into /etc/ifconfig.xxN by 228 # starting a line with "!". Refer to ifconfig.if(5) for details. 229 # 230 if [ "$net_interfaces" != NO ]; then 231 ifaces="$(/sbin/ifconfig -l)" 232 if checkyesno auto_ifconfig; then 233 tmp="$ifaces" 234 for cloner in $(/sbin/ifconfig -C); do 235 for int in /etc/ifconfig.${cloner}[0-9]*; do 236 [ ! -f $int ] && break 237 tmp="$tmp ${int##*.}" 238 done 239 done 240 else 241 tmp="$net_interfaces" 242 fi 243 echo -n 'Configuring network interfaces:' 244 for int in $tmp; do 245 eval argslist=\$ifconfig_$int 246 247 # Skip interfaces that do not have explicit 248 # configuration information. If auto_ifconfig is 249 # false then also warn about such interfaces. 250 # 251 if [ -z "$argslist" ] && ! [ -f /etc/ifconfig.$int ] 252 then 253 if ! checkyesno auto_ifconfig; then 254 echo 255 warn \ 256 "/etc/ifconfig.$int missing and ifconfig_$int not set;" 257 warn "interface $int not configured." 258 fi 259 continue 260 fi 261 262 echo -n " $int" 263 264 # Create the interface if necessary. 265 # If the interface did not exist before, 266 # then also resync ipf(4). 267 # 268 if intmissing $int $ifaces; then 269 if /sbin/ifconfig $int create && \ 270 checkyesno ipfilter; then 271 /sbin/ipf -y >/dev/null 272 fi 273 fi 274 275 # If $ifconfig_xxN is empty, then use 276 # /etc/ifconfig.xxN, which we know exists due to 277 # an earlier test. 278 # 279 # If $ifconfig_xxN is non-empty and contains a 280 # newline, then just use it as is. (This allows 281 # semicolons through unmolested.) 282 # 283 # If $ifconfig_xxN is non-empty and does not 284 # contain a newline, then convert all semicolons 285 # to newlines. 286 # 287 case "$argslist" in 288 '') 289 cat /etc/ifconfig.$int 290 ;; 291 *"${nl}"*) 292 echo "$argslist" 293 ;; 294 *) 295 ( 296 set -o noglob 297 IFS=';'; set -- $argslist 298 #echo >&2 "[$#] [$1] [$2] [$3] [$4]" 299 IFS="$nl"; echo "$*" 300 ) 301 ;; 302 esac | 303 collapse_backslash_newline | 304 while read -r args; do 305 case "$args" in 306 ''|"#"*|create) 307 ;; 308 "!"*) 309 # Run arbitrary command in a subshell. 310 ( eval "${args#*!}" ) 311 ;; 312 dhcp) 313 if ! checkyesno dhcpcd; then 314 /sbin/dhcpcd -n \ 315 ${dhcpcd_flags} $int 316 fi 317 ;; 318 *) 319 # Pass args to ifconfig. Note 320 # that args may contain embedded 321 # shell metacharacters, such as 322 # "ssid 'foo;*>bar'". We eval 323 # one more time so that things 324 # like ssid "Columbia University" work. 325 ( 326 set -o noglob 327 eval set -- $args 328 #echo >&2 "[$#] [$1] [$2] [$3]" 329 /sbin/ifconfig $int "$@" 330 ) 331 ;; 332 esac 333 done 334 configured_interfaces="$configured_interfaces $int" 335 done 336 echo "." 337 fi 338} 339 340network_start_aliases() 341{ 342 echo -n "Adding interface aliases:" 343 344 # Check if each configured interface xxN has an $ifaliases_xxN variable 345 # associated, then configure additional IP addresses for that interface. 346 # The variable contains a list of "address netmask" pairs, with 347 # "netmask" set to "-" if the interface default netmask is to be used. 348 # 349 # Note that $ifaliases_xxN works only in certain cases and its 350 # use is not recommended. Use /etc/ifconfig.xxN or multiple 351 # commands in $ifconfig_xxN instead. 352 # 353 for int in lo0 $configured_interfaces; do 354 eval args=\$ifaliases_$int 355 if [ -n "$args" ]; then 356 set -- $args 357 while [ $# -ge 2 ]; do 358 addr=$1 ; net=$2 ; shift 2 359 if [ "$net" = "-" ]; then 360 # for compatibility only, obsolete 361 /sbin/ifconfig $int inet alias $addr 362 else 363 /sbin/ifconfig $int inet alias $addr \ 364 netmask $net 365 fi 366 echo -n " $int:$addr" 367 done 368 fi 369 done 370 371 # /etc/ifaliases, if it exists, contains the names of additional IP 372 # addresses for each interface. It is formatted as a series of lines 373 # that contain 374 # address interface netmask 375 # 376 # Note that /etc/ifaliases works only in certain cases and its 377 # use is not recommended. Use /etc/ifconfig.xxN or multiple 378 # commands in $ifconfig_xxN instead. 379 # 380 if [ -f /etc/ifaliases ]; then 381 while read addr int net; do 382 if [ -z "$net" ]; then 383 # for compatibility only, obsolete 384 /sbin/ifconfig $int inet alias $addr 385 else 386 /sbin/ifconfig $int inet alias $addr netmask $net 387 fi 388 done < /etc/ifaliases 389 fi 390 391 echo "." # for "Adding interface aliases:" 392} 393 394network_start_defaultroute() 395{ 396 # Check $defaultroute, then /etc/mygate, for the name or address 397 # of my IPv4 gateway host. If using a name, that name must be in 398 # /etc/hosts. 399 # 400 if [ -z "$defaultroute" ] && [ -f /etc/mygate ]; then 401 defaultroute=$(cat /etc/mygate) 402 fi 403 if [ -n "$defaultroute" ]; then 404 /sbin/route add default $defaultroute 405 fi 406} 407 408network_start_defaultroute6() 409{ 410 # Check $defaultroute6, then /etc/mygate6, for the name or address 411 # of my IPv6 gateway host. If using a name, that name must be in 412 # /etc/hosts. Note that the gateway host address must be a link-local 413 # address if it is not using an stf* interface. 414 # 415 if [ -z "$defaultroute6" ] && [ -f /etc/mygate6 ]; then 416 defaultroute6=$(cat /etc/mygate6) 417 fi 418 if [ -n "$defaultroute6" ]; then 419 if [ "$ip6mode" = "autohost" ]; then 420 echo 421 warn \ 422 "ip6mode is set to 'autohost' and a v6 default route is also set." 423 fi 424 /sbin/route add -inet6 default $defaultroute6 425 fi 426} 427 428network_start_ipv6_autoconf() 429{ 430 # IPv6 interface autoconfiguration. 431 # 432 if /sbin/ifconfig lo0 inet6 >/dev/null 2>&1; then 433 # wait till DAD is completed. always invoke it in case 434 # if are configured manually by ifconfig 435 # 436 echo 'Waiting for DAD completion for' \ 437 'statically configured addresses...' 438 dadcount=$(/sbin/sysctl -n net.inet6.ip6.dad_count 2>/dev/null) 439 sleep $dadcount 440 sleep 1 441 442 if checkyesno rtsol; then 443 if [ "$ip6mode" = "autohost" ]; then 444 echo 'Sending router solicitation...' 445 /sbin/rtsol $rtsol_flags 446 else 447 echo 448 warn \ 449 "ip6mode must be set to 'autohost' to use rtsol." 450 fi 451 452 # wait till DAD is completed, for global addresses 453 # configured by router advert message. 454 # 455 echo 'Waiting for DAD completion for' \ 456 'addresses configured by router advert message...' 457 sleep $dadcount 458 sleep 1 459 fi 460 fi 461} 462 463network_start_local() 464{ 465 # XXX this must die 466 if [ -s /etc/netstart.local ]; then 467 sh /etc/netstart.local start 468 fi 469} 470 471network_stop() 472{ 473 echo "Stopping network." 474 475 network_stop_local 476 network_stop_aliases 477 network_stop_interfaces 478 network_stop_route 479} 480 481network_stop_local() 482{ 483 # XXX this must die 484 if [ -s /etc/netstart.local ]; then 485 sh /etc/netstart.local stop 486 fi 487} 488 489network_stop_aliases() 490{ 491 echo "Deleting aliases." 492 if [ -f /etc/ifaliases ]; then 493 while read addr int net; do 494 /sbin/ifconfig $int inet delete $addr 495 done < /etc/ifaliases 496 fi 497 498 for int in $(/sbin/ifconfig -lu); do 499 eval args=\$ifaliases_$int 500 if [ -n "$args" ]; then 501 set -- $args 502 while [ $# -ge 2 ]; do 503 addr=$1 ; net=$2 ; shift 2 504 /sbin/ifconfig $int inet delete $addr 505 done 506 fi 507 done 508} 509 510network_stop_interfaces() 511{ 512 # down interfaces 513 # 514 echo -n 'Downing network interfaces:' 515 if [ "$net_interfaces" != NO ]; then 516 if checkyesno auto_ifconfig; then 517 tmp=$(/sbin/ifconfig -l) 518 else 519 tmp="$net_interfaces" 520 fi 521 for int in $tmp; do 522 eval args=\$ifconfig_$int 523 if [ -n "$args" ] || [ -f /etc/ifconfig.$int ]; then 524 echo -n " $int" 525 if [ -f /var/run/dhcpcd-$int.pid ]; then 526 /sbin/dhcpcd -k $int 2> /dev/null 527 fi 528 /sbin/ifconfig $int down 529 if /sbin/ifconfig $int destroy 2>/dev/null && \ 530 checkyesno ipfilter; then 531 # resync ipf(4) 532 /sbin/ipf -y >/dev/null 533 fi 534 fi 535 done 536 echo "." 537 fi 538} 539 540network_stop_route() 541{ 542 # flush routes 543 # 544 /sbin/route -qn flush 545 546} 547 548load_rc_config $name 549load_rc_config_var dhclient dhclient 550load_rc_config_var dhcpcd dhcpcd 551load_rc_config_var ipfilter ipfilter 552run_rc_command "$1" 553