1#!/bin/sh 2# 3# $NetBSD: network,v 1.77 2020/02/22 11:52:45 roy 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, and for any other 219 # line we run "ifconfig xxN", using each line of the file as the 220 # arguments for a separate "ifconfig" invocation. 221 # 222 # In order to configure an interface reasonably, you at the very least 223 # need to specify "[addr_family] [hostname]" (e.g "inet my.domain.org"), 224 # and probably a netmask (as in "netmask 0xffffffe0"). You will 225 # frequently need to specify a media type, as in "media UTP", for 226 # interface cards with multiple media connections that do not 227 # autoconfigure. See the ifconfig manual page for details. 228 # 229 # Note that /etc/ifconfig.xxN takes multiple lines. The following 230 # configuration is possible: 231 # inet 10.1.1.1 netmask 0xffffff00 232 # inet 10.1.1.2 netmask 0xffffff00 alias 233 # inet6 2001:db8::1 prefixlen 64 alias 234 # 235 # You can put shell script fragment into /etc/ifconfig.xxN by 236 # starting a line with "!". Refer to ifconfig.if(5) for details. 237 # 238 ifaces="$(/sbin/ifconfig -l)" 239 if checkyesno auto_ifconfig; then 240 tmp="$ifaces" 241 for cloner in $(/sbin/ifconfig -C); do 242 for int in /etc/ifconfig.${cloner}[0-9]*; do 243 [ ! -f $int ] && break 244 tmp="$tmp ${int##*.}" 245 done 246 done 247 else 248 tmp="$net_interfaces" 249 fi 250 echo -n 'Configuring network interfaces:' 251 for int in $tmp; do 252 eval argslist=\$ifconfig_$int 253 254 # Skip interfaces that do not have explicit 255 # configuration information. If auto_ifconfig is 256 # false then also warn about such interfaces. 257 # 258 if [ -z "$argslist" ] && ! [ -f /etc/ifconfig.$int ] 259 then 260 if ! checkyesno auto_ifconfig; then 261 echo 262 warn \ 263 "/etc/ifconfig.$int missing and ifconfig_$int not set;" 264 warn "interface $int not configured." 265 fi 266 continue 267 fi 268 269 echo -n " $int" 270 271 # Create the interface if necessary. 272 # If the interface did not exist before, 273 # then also resync ipf(4). 274 # 275 if intmissing $int $ifaces; then 276 if /sbin/ifconfig $int create && \ 277 checkyesno ipfilter; then 278 /sbin/ipf -y >/dev/null 279 fi 280 fi 281 282 # If $ifconfig_xxN is empty, then use 283 # /etc/ifconfig.xxN, which we know exists due to 284 # an earlier test. 285 # 286 # If $ifconfig_xxN is non-empty and contains a 287 # newline, then just use it as is. (This allows 288 # semicolons through unmolested.) 289 # 290 # If $ifconfig_xxN is non-empty and does not 291 # contain a newline, then convert all semicolons 292 # to newlines. 293 # 294 case "$argslist" in 295 '') 296 cat /etc/ifconfig.$int 297 ;; 298 *"${nl}"*) 299 echo "$argslist" 300 ;; 301 *) 302 ( 303 set -o noglob 304 IFS=';'; set -- $argslist 305 #echo >&2 "[$#] [$1] [$2] [$3] [$4]" 306 IFS="$nl"; echo "$*" 307 ) 308 ;; 309 esac | 310 collapse_backslash_newline | 311 while read -r args; do 312 case "$args" in 313 ''|"#"*|create) 314 ;; 315 "!"*) 316 # Run arbitrary command in a subshell. 317 ( eval "${args#*!}" ) 318 ;; 319 dhcp) 320 if ! checkyesno dhcpcd; then 321 /sbin/dhcpcd -n \ 322 ${dhcpcd_flags} $int 323 fi 324 ;; 325 *) 326 # Pass args to ifconfig. Note 327 # that args may contain embedded 328 # shell metacharacters, such as 329 # "ssid 'foo;*>bar'". We eval 330 # one more time so that things 331 # like ssid "Columbia University" work. 332 ( 333 set -o noglob 334 eval set -- $args 335 #echo >&2 "[$#] [$1] [$2] [$3]" 336 /sbin/ifconfig $int "$@" 337 ) 338 ;; 339 esac 340 done 341 configured_interfaces="$configured_interfaces $int" 342 done 343 echo "." 344} 345 346network_start_aliases() 347{ 348 echo -n "Adding interface aliases:" 349 350 # Check if each configured interface xxN has an $ifaliases_xxN variable 351 # associated, then configure additional IP addresses for that interface. 352 # The variable contains a list of "address netmask" pairs, with 353 # "netmask" set to "-" if the interface default netmask is to be used. 354 # 355 # Note that $ifaliases_xxN works only in certain cases and its 356 # use is not recommended. Use /etc/ifconfig.xxN or multiple 357 # commands in $ifconfig_xxN instead. 358 # 359 for int in lo0 $configured_interfaces; do 360 eval args=\$ifaliases_$int 361 if [ -n "$args" ]; then 362 set -- $args 363 while [ $# -ge 2 ]; do 364 addr=$1 ; net=$2 ; shift 2 365 if [ "$net" = "-" ]; then 366 # for compatibility only, obsolete 367 /sbin/ifconfig $int inet alias $addr 368 else 369 /sbin/ifconfig $int inet alias $addr \ 370 netmask $net 371 fi 372 echo -n " $int:$addr" 373 done 374 fi 375 done 376 377 # /etc/ifaliases, if it exists, contains the names of additional IP 378 # addresses for each interface. It is formatted as a series of lines 379 # that contain 380 # address interface netmask 381 # 382 # Note that /etc/ifaliases works only in certain cases and its 383 # use is not recommended. Use /etc/ifconfig.xxN or multiple 384 # commands in $ifconfig_xxN instead. 385 # 386 if [ -f /etc/ifaliases ]; then 387 while read addr int net; do 388 if [ -z "$net" ]; then 389 # for compatibility only, obsolete 390 /sbin/ifconfig $int inet alias $addr 391 else 392 /sbin/ifconfig $int inet alias $addr netmask $net 393 fi 394 done < /etc/ifaliases 395 fi 396 397 echo "." # for "Adding interface aliases:" 398} 399 400network_start_defaultroute() 401{ 402 # Check $defaultroute, then /etc/mygate, for the name or address 403 # of my IPv4 gateway host. If using a name, that name must be in 404 # /etc/hosts. 405 # 406 if [ -z "$defaultroute" ] && [ -f /etc/mygate ]; then 407 defaultroute=$(kat /etc/mygate) 408 fi 409 if [ -n "$defaultroute" ]; then 410 /sbin/route add default $defaultroute 411 fi 412} 413 414network_start_defaultroute6() 415{ 416 # Check $defaultroute6, then /etc/mygate6, for the name or address 417 # of my IPv6 gateway host. If using a name, that name must be in 418 # /etc/hosts. Note that the gateway host address must be a link-local 419 # address if it is not using an stf* interface. 420 # 421 if [ -z "$defaultroute6" ] && [ -f /etc/mygate6 ]; then 422 defaultroute6=$(kat /etc/mygate6) 423 fi 424 if [ -n "$defaultroute6" ]; then 425 if [ "$ip6mode" = "autohost" ]; then 426 echo 427 warn \ 428 "ip6mode is set to 'autohost' and a v6 default route is also set." 429 fi 430 /sbin/route add -inet6 default $defaultroute6 431 fi 432} 433 434network_start_ipv6_autoconf() 435{ 436 # IPv6 interface autoconfiguration. 437 438 # dhcpcd will ensure DAD completes before forking 439 if checkyesnox rtsol && ! checkyesno dhcpcd; then 440 if [ "$ip6mode" = "autohost" ]; then 441 echo 442 warn "rtsol has been removed, " \ 443 "please configure dhcpcd in its place." 444 fi 445 fi 446} 447 448network_wait_dad() 449{ 450 # Wait for the DAD flags to clear from all addresses. 451 if [ -n "$ifconfig_wait_dad_flags" ]; then 452 echo "Waiting for duplicate address detection to finish..." 453 ifconfig $ifconfig_wait_dad_flags 454 fi 455} 456 457network_start_resolv() 458{ 459 resconf= 460 461 if [ -n "$dns_domain" ]; then 462 resconf="${resconf}domain $dns_domain$nl" 463 fi 464 if [ -n "$dns_search" ]; then 465 resconf="${resconf}search $dns_search$nl" 466 fi 467 for n in $dns_nameservers; do 468 resconf="${resconf}nameserver $n$nl" 469 done 470 if [ -n "$dns_sortlist" ]; then 471 resconf="${resconf}sortlist $dns_sortlist$nl" 472 fi 473 if [ -n "$dns_options" ]; then 474 resconf="${resconf}options $dns_options$nl" 475 fi 476 if [ -n "$resconf" ]; then 477 resconf="# Generated by /etc/rc.d/network$nl$resconf" 478 echo 'Configuring resolv.conf' 479 printf %s "$resconf" | resolvconf -m "${dns_metric:-0}" -a network 480 fi 481} 482 483network_start_local() 484{ 485 # XXX this must die 486 if [ -s /etc/netstart.local ]; then 487 sh /etc/netstart.local start 488 fi 489} 490 491network_stop() 492{ 493 echo "Stopping network." 494 495 network_stop_local 496 network_stop_resolv 497 network_stop_aliases 498 [ "$net_interfaces" != NO ] && 499 network_stop_interfaces 500 network_stop_route 501} 502 503network_stop_local() 504{ 505 # XXX this must die 506 if [ -s /etc/netstart.local ]; then 507 sh /etc/netstart.local stop 508 fi 509} 510 511network_stop_resolv() 512{ 513 resolvconf -f -d network 514} 515 516network_stop_aliases() 517{ 518 echo "Deleting aliases." 519 if [ -f /etc/ifaliases ]; then 520 while read addr int net; do 521 /sbin/ifconfig $int inet delete $addr 522 done < /etc/ifaliases 523 fi 524 525 for int in $(/sbin/ifconfig -lu); do 526 eval args=\$ifaliases_$int 527 if [ -n "$args" ]; then 528 set -- $args 529 while [ $# -ge 2 ]; do 530 addr=$1 ; net=$2 ; shift 2 531 /sbin/ifconfig $int inet delete $addr 532 done 533 fi 534 done 535} 536 537network_stop_interfaces() 538{ 539 # down interfaces 540 # 541 echo -n 'Downing network interfaces:' 542 if checkyesno auto_ifconfig; then 543 tmp=$(/sbin/ifconfig -l) 544 else 545 tmp="$net_interfaces" 546 fi 547 for int in $tmp; do 548 eval args=\$ifconfig_$int 549 if [ -n "$args" ] || [ -f /etc/ifconfig.$int ]; then 550 echo -n " $int" 551 if [ -f /var/run/dhcpcd-$int.pid ]; then 552 /sbin/dhcpcd -k $int 2> /dev/null 553 fi 554 /sbin/ifconfig $int down 555 if /sbin/ifconfig $int destroy 2>/dev/null && \ 556 checkyesno ipfilter; then 557 # resync ipf(4) 558 /sbin/ipf -y >/dev/null 559 fi 560 fi 561 done 562 echo "." 563} 564 565network_stop_route() 566{ 567 # flush routes 568 # 569 if checkyesno flushroutes; then 570 /sbin/route -qn flush 571 fi 572} 573 574load_rc_config $name 575load_rc_config_var dhcpcd dhcpcd 576load_rc_config_var ipfilter ipfilter 577run_rc_command "$1" 578