network revision 1.78
1#!/bin/sh 2# 3# $NetBSD: network,v 1.78 2020/04/15 20:31:57 kim 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{ 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_start_ipv6_autoconf 54 network_wait_dad 55 network_start_resolv 56 network_start_local 57} 58 59network_start_hostname() 60{ 61 # If $hostname is set, use it for my Internet name, 62 # otherwise use /etc/myname 63 # 64 if [ -z "$hostname" ] && [ -f /etc/myname ]; then 65 hostname=$(kat /etc/myname) 66 fi 67 if [ -n "$hostname" ]; then 68 echo "Hostname: $hostname" 69 hostname $hostname 70 else 71 # Don't warn about it if we're going to run 72 # DHCP later, as we will probably get the 73 # hostname at that time. 74 # 75 if ! checkyesno dhcpcd && \ 76 [ -z "$(hostname)" ] 77 then 78 warn "\$hostname not set." 79 fi 80 fi 81} 82 83network_start_domainname() 84{ 85 # Check $domainname first, then /etc/defaultdomain, 86 # for NIS/YP domain name 87 # 88 if [ -z "$domainname" ] && [ -f /etc/defaultdomain ]; then 89 domainname=$(kat /etc/defaultdomain) 90 fi 91 if [ -n "$domainname" ]; then 92 echo "NIS domainname: $domainname" 93 domainname $domainname 94 fi 95 96 # Flush all routes just to make sure it is clean 97 if checkyesno flushroutes; then 98 /sbin/route -qn flush 99 fi 100} 101 102network_start_loopback() 103{ 104 # Set the address for the first loopback interface, so that the 105 # auto-route from a newly configured interface's address to lo0 106 # works correctly. 107 # 108 # NOTE: obscure networking problems will occur if lo0 isn't configured. 109 # 110 /sbin/ifconfig lo0 inet 127.0.0.1 111 112 # According to RFC1122, 127.0.0.0/8 must not leave the node. 113 # 114 /sbin/route -q add -inet 127.0.0.0 -netmask 0xff000000 127.0.0.1 -reject 115} 116 117network_start_ipv6_route() 118{ 119 # IPv6 routing setups, and host/router mode selection. 120 # 121 # We have IPv6 support in kernel. 122 123 # disallow link-local unicast dest without outgoing scope 124 # identifiers. 125 # 126 /sbin/route -q add -inet6 fe80:: -prefixlen 10 ::1 -reject 127 128 # disallow the use of the RFC3849 documentation address 129 # 130 /sbin/route -q add -inet6 2001:db8:: -prefixlen 32 ::1 -reject 131 132 # IPv6 site-local scoped address prefix (fec0::/10) 133 # has been deprecated by RFC3879. 134 # 135 if [ -n "$ip6sitelocal" ]; then 136 warn "\$ip6sitelocal is no longer valid" 137 fi 138 139 # disallow "internal" addresses to appear on the wire. 140 # 141 /sbin/route -q add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject 142 143 # disallow packets to malicious IPv4 compatible prefix 144 # 145 /sbin/route -q add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject 146 /sbin/route -q add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject 147 /sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject 148 /sbin/route -q add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject 149 150 # disallow packets to malicious 6to4 prefix 151 # 152 /sbin/route -q add -inet6 2002:e000:: -prefixlen 20 ::1 -reject 153 /sbin/route -q add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject 154 /sbin/route -q add -inet6 2002:0000:: -prefixlen 24 ::1 -reject 155 /sbin/route -q add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject 156 157 # Completely disallow packets to IPv4 compatible prefix. 158 # This may conflict with RFC1933 under following circumstances: 159 # (1) An IPv6-only KAME node tries to originate packets to IPv4 160 # compatible destination. The KAME node has no IPv4 161 # compatible support. Under RFC1933, it should transmit 162 # native IPv6 packets toward IPv4 compatible destination, 163 # hoping it would reach a router that forwards the packet 164 # toward auto-tunnel interface. 165 # (2) An IPv6-only node originates a packet to IPv4 compatible 166 # destination. A KAME node is acting as an IPv6 router, and 167 # asked to forward it. 168 # Due to rare use of IPv4 compatible address, and security 169 # issues with it, we disable it by default. 170 # 171 /sbin/route -q add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject 172 173 /sbin/sysctl -qw net.inet6.ip6.forwarding=0 174 /sbin/sysctl -qw net.inet6.ip6.accept_rtadv=0 175 176 case $ip6mode in 177 router) 178 echo 'IPv6 mode: router' 179 /sbin/sysctl -qw net.inet6.ip6.forwarding=1 180 181 # disallow unique-local unicast forwarding without 182 # explicit configuration. 183 if ! checkyesno ip6uniquelocal; then 184 /sbin/route -q add -inet6 fc00:: -prefixlen 7 \ 185 ::1 -reject 186 fi 187 ;; 188 189 autohost) 190 echo 'IPv6 mode: autoconfigured host' 191 /sbin/sysctl -qw net.inet6.ip6.accept_rtadv=1 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 \ 323 ${dhcpcd_flags} $int 324 fi 325 ;; 326 rtsol) 327 if ! checkyesno dhcpcd; then 328 /sbin/sysctl -qw \ 329 net.inet6.ip6.accept_rtadv=1 330 /sbin/dhcpcd -q6T --nodhcp6 $int 331 fi 332 ;; 333 *) 334 # Pass args to ifconfig. Note 335 # that args may contain embedded 336 # shell metacharacters, such as 337 # "ssid 'foo;*>bar'". We eval 338 # one more time so that things 339 # like ssid "Columbia University" work. 340 ( 341 set -o noglob 342 eval set -- $args 343 #echo >&2 "[$#] [$1] [$2] [$3]" 344 /sbin/ifconfig $int "$@" 345 ) 346 ;; 347 esac 348 done 349 configured_interfaces="$configured_interfaces $int" 350 done 351 echo "." 352} 353 354network_start_aliases() 355{ 356 echo -n "Adding interface aliases:" 357 358 # Check if each configured interface xxN has an $ifaliases_xxN variable 359 # associated, then configure additional IP addresses for that interface. 360 # The variable contains a list of "address netmask" pairs, with 361 # "netmask" set to "-" if the interface default netmask is to be used. 362 # 363 # Note that $ifaliases_xxN works only in certain cases and its 364 # use is not recommended. Use /etc/ifconfig.xxN or multiple 365 # commands in $ifconfig_xxN instead. 366 # 367 for int in lo0 $configured_interfaces; do 368 eval args=\$ifaliases_$int 369 if [ -n "$args" ]; then 370 set -- $args 371 while [ $# -ge 2 ]; do 372 addr=$1 ; net=$2 ; shift 2 373 if [ "$net" = "-" ]; then 374 # for compatibility only, obsolete 375 /sbin/ifconfig $int inet alias $addr 376 else 377 /sbin/ifconfig $int inet alias $addr \ 378 netmask $net 379 fi 380 echo -n " $int:$addr" 381 done 382 fi 383 done 384 385 # /etc/ifaliases, if it exists, contains the names of additional IP 386 # addresses for each interface. It is formatted as a series of lines 387 # that contain 388 # address interface netmask 389 # 390 # Note that /etc/ifaliases works only in certain cases and its 391 # use is not recommended. Use /etc/ifconfig.xxN or multiple 392 # commands in $ifconfig_xxN instead. 393 # 394 if [ -f /etc/ifaliases ]; then 395 while read addr int net; do 396 if [ -z "$net" ]; then 397 # for compatibility only, obsolete 398 /sbin/ifconfig $int inet alias $addr 399 else 400 /sbin/ifconfig $int inet alias $addr netmask $net 401 fi 402 done < /etc/ifaliases 403 fi 404 405 echo "." # for "Adding interface aliases:" 406} 407 408network_start_defaultroute() 409{ 410 # Check $defaultroute, then /etc/mygate, for the name or address 411 # of my IPv4 gateway host. If using a name, that name must be in 412 # /etc/hosts. 413 # 414 if [ -z "$defaultroute" ] && [ -f /etc/mygate ]; then 415 defaultroute=$(kat /etc/mygate) 416 fi 417 if [ -n "$defaultroute" ]; then 418 /sbin/route add default $defaultroute 419 fi 420} 421 422network_start_defaultroute6() 423{ 424 # Check $defaultroute6, then /etc/mygate6, for the name or address 425 # of my IPv6 gateway host. If using a name, that name must be in 426 # /etc/hosts. Note that the gateway host address must be a link-local 427 # address if it is not using an stf* interface. 428 # 429 if [ -z "$defaultroute6" ] && [ -f /etc/mygate6 ]; then 430 defaultroute6=$(kat /etc/mygate6) 431 fi 432 if [ -n "$defaultroute6" ]; then 433 if [ "$ip6mode" = "autohost" ]; then 434 echo 435 warn \ 436 "ip6mode is set to 'autohost' and a v6 default route is also set." 437 fi 438 /sbin/route add -inet6 default $defaultroute6 439 fi 440} 441 442network_start_ipv6_autoconf() 443{ 444 # IPv6 interface autoconfiguration. 445 446 # dhcpcd will ensure DAD completes before forking 447 if checkyesnox rtsol && ! checkyesno dhcpcd; then 448 if [ "$ip6mode" = "autohost" ]; then 449 echo 450 warn "rtsol has been removed, " \ 451 "please configure dhcpcd in its place." 452 fi 453 fi 454} 455 456network_wait_dad() 457{ 458 # Wait for the DAD flags to clear from all addresses. 459 if [ -n "$ifconfig_wait_dad_flags" ]; then 460 echo "Waiting for duplicate address detection to finish..." 461 ifconfig $ifconfig_wait_dad_flags 462 fi 463} 464 465network_start_resolv() 466{ 467 resconf= 468 469 if [ -n "$dns_domain" ]; then 470 resconf="${resconf}domain $dns_domain$nl" 471 fi 472 if [ -n "$dns_search" ]; then 473 resconf="${resconf}search $dns_search$nl" 474 fi 475 for n in $dns_nameservers; do 476 resconf="${resconf}nameserver $n$nl" 477 done 478 if [ -n "$dns_sortlist" ]; then 479 resconf="${resconf}sortlist $dns_sortlist$nl" 480 fi 481 if [ -n "$dns_options" ]; then 482 resconf="${resconf}options $dns_options$nl" 483 fi 484 if [ -n "$resconf" ]; then 485 resconf="# Generated by /etc/rc.d/network$nl$resconf" 486 echo 'Configuring resolv.conf' 487 printf %s "$resconf" | resolvconf -m "${dns_metric:-0}" -a network 488 fi 489} 490 491network_start_local() 492{ 493 # XXX this must die 494 if [ -s /etc/netstart.local ]; then 495 sh /etc/netstart.local start 496 fi 497} 498 499network_stop() 500{ 501 echo "Stopping network." 502 503 network_stop_local 504 network_stop_resolv 505 network_stop_aliases 506 [ "$net_interfaces" != NO ] && 507 network_stop_interfaces 508 network_stop_route 509} 510 511network_stop_local() 512{ 513 # XXX this must die 514 if [ -s /etc/netstart.local ]; then 515 sh /etc/netstart.local stop 516 fi 517} 518 519network_stop_resolv() 520{ 521 resolvconf -f -d network 522} 523 524network_stop_aliases() 525{ 526 echo "Deleting aliases." 527 if [ -f /etc/ifaliases ]; then 528 while read addr int net; do 529 /sbin/ifconfig $int inet delete $addr 530 done < /etc/ifaliases 531 fi 532 533 for int in $(/sbin/ifconfig -lu); do 534 eval args=\$ifaliases_$int 535 if [ -n "$args" ]; then 536 set -- $args 537 while [ $# -ge 2 ]; do 538 addr=$1 ; net=$2 ; shift 2 539 /sbin/ifconfig $int inet delete $addr 540 done 541 fi 542 done 543} 544 545network_stop_interfaces() 546{ 547 # down interfaces 548 # 549 echo -n 'Downing network interfaces:' 550 if checkyesno auto_ifconfig; then 551 tmp=$(/sbin/ifconfig -l) 552 else 553 tmp="$net_interfaces" 554 fi 555 for int in $tmp; do 556 eval args=\$ifconfig_$int 557 if [ -n "$args" ] || [ -f /etc/ifconfig.$int ]; then 558 echo -n " $int" 559 if [ -f /var/run/dhcpcd-$int.pid ]; then 560 /sbin/dhcpcd -k $int 2> /dev/null 561 fi 562 /sbin/ifconfig $int down 563 if /sbin/ifconfig $int destroy 2>/dev/null && \ 564 checkyesno ipfilter; then 565 # resync ipf(4) 566 /sbin/ipf -y >/dev/null 567 fi 568 fi 569 done 570 echo "." 571} 572 573network_stop_route() 574{ 575 # flush routes 576 # 577 if checkyesno flushroutes; then 578 /sbin/route -qn flush 579 fi 580} 581 582load_rc_config $name 583load_rc_config_var dhcpcd dhcpcd 584load_rc_config_var ipfilter ipfilter 585run_rc_command "$1" 586