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