1df930be7Sderaadt#!/bin/sh - 2df930be7Sderaadt# 3*8222f376Srpe# $OpenBSD: netstart,v 1.177 2017/04/24 20:31:48 rpe Exp $ 45116749bSrpe 55116749bSrpe# Turn off Strict Bourne shell mode. 65116749bSrpeset +o sh 78fc5e153Smillert 8952fbff6Srpe# Echo file $1 to stdout. Skip comment lines and delete everything 9952fbff6Srpe# after the first '#' from other lines. Strip leading and trailing 10952fbff6Srpe# whitespace if IFS is set. 11e57a083bSrpe# Usage: stripcom /path/to/file 128fc5e153Smillertstripcom() { 13e57a083bSrpe local _file=$1 _line 14e57a083bSrpe 15e57a083bSrpe [[ -f $_file ]] || return 16e57a083bSrpe 17e57a083bSrpe while read _line; do 18e57a083bSrpe [[ -n ${_line%%#*} ]] && print -r -- "$_line" 19e57a083bSrpe done <$_file 208fc5e153Smillert} 2104e0ac27Smillert 22*8222f376Srpe# Parse and "unpack" a hostname.if(5) line given as positional parameters. 23*8222f376Srpe# Fill the _cmds array with the resulting interface configuration commands. 24*8222f376Srpeparse_hn_line() { 25*8222f376Srpe local _af=0 _name=1 _mask=2 _bc=3 _prefix=2 _c _cmd _prev _daddr 26*8222f376Srpe set -A _c -- "$@" 27*8222f376Srpe set -o noglob 28*8222f376Srpe 29*8222f376Srpe case ${_c[_af]} in 30*8222f376Srpe ''|*([[:blank:]])'#'*) 31*8222f376Srpe return 32*8222f376Srpe ;; 33*8222f376Srpe inet) ((${#_c[*]} > 1)) || return 34*8222f376Srpe [[ ${_c[_name]} == alias ]] && _mask=3 _bc=4 35*8222f376Srpe [[ -n ${_c[_mask]} ]] && _c[_mask]="netmask ${_c[_mask]}" 36*8222f376Srpe if [[ -n ${_c[_bc]} ]]; then 37*8222f376Srpe _c[_bc]="broadcast ${_c[_bc]}" 38*8222f376Srpe [[ ${_c[_bc]} == *NONE ]] && _c[_bc]= 39*8222f376Srpe fi 40*8222f376Srpe _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}" 41*8222f376Srpe ;; 42*8222f376Srpe inet6) ((${#_c[*]} > 1)) || return 43*8222f376Srpe if [[ ${_c[_name]} == autoconf ]]; then 44*8222f376Srpe _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}" 45*8222f376Srpe rtsolif="$rtsolif $_if" 46*8222f376Srpe return 47*8222f376Srpe fi 48*8222f376Srpe [[ ${_c[_name]} == alias ]] && _prefix=3 49*8222f376Srpe [[ -n ${_c[_prefix]} ]] && _c[_prefix]="prefixlen ${_c[_prefix]}" 50*8222f376Srpe _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}" 51*8222f376Srpe ;; 52*8222f376Srpe dest) ((${#_c[*]} == 2)) && _daddr=${_c[1]} || return 53*8222f376Srpe _prev=$((${#_cmds[*]} - 1)) 54*8222f376Srpe ((_prev >= 0)) || return 55*8222f376Srpe set -A _c -- ${_cmds[_prev]} 56*8222f376Srpe _name=3 57*8222f376Srpe [[ ${_c[_name]} == alias ]] && _name=4 58*8222f376Srpe _c[_name]="${_c[_name]} $_daddr" 59*8222f376Srpe _cmds[$_prev]="${_c[@]}" 60*8222f376Srpe ;; 61*8222f376Srpe dhcp) _c[0]= 62*8222f376Srpe _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]} down;dhclient $_if" 63*8222f376Srpe dhcpif="$dhcpif $_if" 64*8222f376Srpe ;; 65*8222f376Srpe rtsol) # XXX Support the rtsol keyword for some time to enable a smooth 66*8222f376Srpe # XXX transition to autoconf. 67*8222f376Srpe _c[0]= 68*8222f376Srpe _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]} up" 69*8222f376Srpe _cmds[${#_cmds[*]}]="ifconfig $_if inet6 autoconf" 70*8222f376Srpe rtsolif="$rtsolif $_if" 71*8222f376Srpe ;; 72*8222f376Srpe '!'*) _cmd=$(print -- "${_c[@]}" | sed 's/\$if/'$_if'/g') 73*8222f376Srpe _cmds[${#_cmds[*]}]="${_cmd#!}" 74*8222f376Srpe ;; 75*8222f376Srpe *) _cmds[${#_cmds[*]}]="ifconfig $_if ${_c[@]}" 76*8222f376Srpe ;; 77*8222f376Srpe esac 78*8222f376Srpe unset _c 79*8222f376Srpe} 80*8222f376Srpe 81e57a083bSrpe# Start a single interface. 82e57a083bSrpe# Usage: ifstart if1 83dfc209d0Smiodifstart() { 84*8222f376Srpe local _if=$1 _file=$HN_DIR/hostname.$1 _cmds _i=0 _line _stat 85*8222f376Srpe set -A _cmds 8624811c97Srpe 87dfc209d0Smiod # Interface names must be alphanumeric only. We check to avoid 88dfc209d0Smiod # configuring backup or temp files, and to catch the "*" case. 89*8222f376Srpe [[ $_if != +([[:alpha:]])+([[:digit:]]) ]] && return 90dfc209d0Smiod 917178fdf4Srpe if [[ ! -f $_file ]]; then 927178fdf4Srpe echo "netstart: $_file: No such file or directory" 9349352c7bStodd return 9449352c7bStodd fi 95*8222f376Srpe 96300d0407Srpe # Not using stat(1), we can't rely on having /usr yet. 977178fdf4Srpe set -A _stat -- $(ls -nL $_file) 987178fdf4Srpe if [ "${_stat[0]#???????} ${_stat[2]} ${_stat[3]}" != "--- 0 0" ]; then 997178fdf4Srpe echo "WARNING: $_file is insecure, fixing permissions" 1007178fdf4Srpe chmod -LR o-rwx $_file 1017178fdf4Srpe chown -LR root.wheel $_file 102bc53e65aSderaadt fi 103dfc209d0Smiod 104*8222f376Srpe # Check for ifconfig'able interface, except if -n option is specified. 105*8222f376Srpe if ! $PRINT_ONLY; then 106*8222f376Srpe (ifconfig $_if || ifconfig $_if create) >/dev/null 2>&1 || 1072817040cStodd return 1082817040cStodd fi 109*8222f376Srpe 110*8222f376Srpe # Parse the hostname.if(5) file and fill _cmds array with interface 111*8222f376Srpe # configuration commands. 112*8222f376Srpe set -o noglob 113*8222f376Srpe while IFS= read -- _line; do 114*8222f376Srpe parse_hn_line $_line 1157178fdf4Srpe done <$_file 116*8222f376Srpe 117*8222f376Srpe # Apply the interface configuration commands stored in _cmds array. 118*8222f376Srpe while ((_i < ${#_cmds[*]})); do 119*8222f376Srpe if $PRINT_ONLY; then 120*8222f376Srpe print -r -- "${_cmds[_i]}" 121*8222f376Srpe else 122*8222f376Srpe eval "${_cmds[_i]}" 123*8222f376Srpe fi 124*8222f376Srpe ((_i++)) 125*8222f376Srpe done 126*8222f376Srpe unset _cmds 127dfc209d0Smiod} 128dfc209d0Smiod 129dde523b1Srpe# Start multiple interfaces by driver name. 130dde523b1Srpe# Usage: ifmstart "em iwm" "trunk vlan" 131300d0407Srpe# Start "$1" interfaces in order or all interfaces if empty. 132dde523b1Srpe# Don't start "$2" interfaces. "$2" is optional. 1339ac6b043Stoddifmstart() { 134dde523b1Srpe local _sifs=$1 _xifs=$2 _hn _if _sif _xif 135dde523b1Srpe 136dde523b1Srpe for _sif in ${_sifs:-ALL}; do 137dde523b1Srpe for _hn in /etc/hostname.*; do 138dde523b1Srpe _if=${_hn#/etc/hostname.} 139dde523b1Srpe [[ $_if == '*' ]] && continue 1409ac6b043Stodd 141300d0407Srpe # Skip unwanted ifs. 142dde523b1Srpe for _xif in $_xifs; do 143dde523b1Srpe [[ $_xif == ${_if%%[0-9]*} ]] && continue 2 1449ac6b043Stodd done 1459ac6b043Stodd 146300d0407Srpe # Start wanted ifs. 147dde523b1Srpe [[ $_sif == @(ALL|${_if%%[0-9]*}) ]] && ifstart $_if 1489ac6b043Stodd done 1499ac6b043Stodd done 1509ac6b043Stodd} 1519ac6b043Stodd 15293230e63Srpe# IPv6 autoconf the interfaces in the $rtsolif list. 15393230e63Srpe# Usage: ifv6autoconf 15493230e63Srpeifv6autoconf() { 15593230e63Srpe local _if 15693230e63Srpe 1576125fd66Ssthen # $ip6kernel will not have been set if we were invoked with a 1586125fd66Ssthen # list of interface names 15993230e63Srpe ifconfig lo0 inet6 >/dev/null 2>&1 || return 0 16093230e63Srpe 16193230e63Srpe for _if in $rtsolif; do 16293230e63Srpe ifconfig $_if inet6 autoconf 1636125fd66Ssthen done 1646125fd66Ssthen} 1656125fd66Ssthen 16605102370Smpi# Parse /etc/mygate and add default routes for IPv4 and IPv6 16705102370Smpi# Usage: defaultroute 16805102370Smpidefaultroute() { 16905102370Smpi [[ -z $dhcpif ]] && stripcom /etc/mygate | while read gw; do 17005102370Smpi [[ $gw == @(*:*) ]] && continue 17105102370Smpi route -qn delete default >/dev/null 2>&1 17205102370Smpi route -qn add -host default $gw && break 17305102370Smpi done 17405102370Smpi [[ -z $rtsolif ]] && stripcom /etc/mygate | while read gw; do 17505102370Smpi [[ $gw == !(*:*) ]] && continue 17605102370Smpi route -qn delete -inet6 default >/dev/null 2>&1 17705102370Smpi route -qn add -host -inet6 default $gw && break 17805102370Smpi done 17905102370Smpi} 18005102370Smpi 18102723c93Sjasper# Make sure the invoking user has the right privileges. 18202723c93Sjasperif (($(id -u) != 0)); then 18302723c93Sjasper echo "${0##*/}: need root privileges" 18402723c93Sjasper exit 1 18502723c93Sjasperfi 18602723c93Sjasper 187a035c1adSrpe# Get network related vars from rc.conf using the parsing routine from rc.subr. 188a035c1adSrpeFUNCS_ONLY=1 . /etc/rc.d/rc.subr 1898799e9c8Srobert_rc_parse_conf 1900dc37902Sangelos 191*8222f376SrpeHN_DIR=${HN_DIR:-/etc} 192*8222f376SrpePRINT_ONLY=false 193*8222f376SrpeUSAGE="USAGE: ${0##*/} [-n] [interface ...]" 194*8222f376Srpewhile getopts ":n" opt; do 195*8222f376Srpe case $opt in 196*8222f376Srpe n) PRINT_ONLY=true;; 197*8222f376Srpe *) print -u2 "$USAGE"; exit 1;; 198*8222f376Srpe esac 199*8222f376Srpedone 200*8222f376Srpeshift $((OPTIND-1)) 201*8222f376Srpe 202*8222f376Srpe# Option -n is only supported if interface names are specified as parameters. 203*8222f376Srpeif $PRINT_ONLY && (($# == 0)); then 204*8222f376Srpe print -u2 "Missing parameters.\n$USAGE" 205*8222f376Srpe exit 1 206*8222f376Srpefi 207*8222f376Srpe 208dfc209d0Smiod# If we were invoked with a list of interface names, just reconfigure these 20905102370Smpi# interfaces (or bridges), add default routes and return. 2100a295e45Srpeif (($# > 0)); then 2110a295e45Srpe for _if; do ifstart $_if; done 21293230e63Srpe ifv6autoconf 21305102370Smpi defaultroute 214dfc209d0Smiod return 215dfc209d0Smiodfi 216dfc209d0Smiod 217dfc209d0Smiod# Otherwise, process with the complete network initialization. 218dfc209d0Smiod 219300d0407Srpe# /etc/myname contains my symbolic name. 2200a295e45Srpe[[ -f /etc/myname ]] && hostname "$(stripcom /etc/myname)" 22137bbdc83Shenning 2224fbd02fcSsobrado# Set the address for the loopback interface. Bringing the interface up, 2234fbd02fcSsobrado# automatically invokes the IPv6 address ::1. 224d216f73bShenningifconfig lo0 inet 127.0.0.1/8 22598c28033Skstailey 2263d8fed7cSitojunif ifconfig lo0 inet6 >/dev/null 2>&1; then 2273d8fed7cSitojun # IPv6 configurations. 2283d8fed7cSitojun ip6kernel=YES 2293d8fed7cSitojun 230dfc209d0Smiod # Disallow link-local unicast dest without outgoing scope identifiers. 23103056e2eSderaadt route -qn add -inet6 fe80:: -prefixlen 10 ::1 -reject >/dev/null 23292aceabbSitojun 233dfc209d0Smiod # Disallow site-local unicast dest without outgoing scope identifiers. 23492aceabbSitojun # If you configure site-locals without scope id (it is permissible 23592aceabbSitojun # config for routers that are not on scope boundary), you may want 23692aceabbSitojun # to comment the line out. 23703056e2eSderaadt route -qn add -inet6 fec0:: -prefixlen 10 ::1 -reject >/dev/null 23892aceabbSitojun 239dfc209d0Smiod # Disallow "internal" addresses to appear on the wire. 24003056e2eSderaadt route -qn add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject >/dev/null 24192aceabbSitojun 242dfc209d0Smiod # Disallow packets to malicious IPv4 compatible prefix. 24303056e2eSderaadt route -qn add -inet6 ::224.0.0.0 -prefixlen 100 ::1 -reject >/dev/null 24403056e2eSderaadt route -qn add -inet6 ::127.0.0.0 -prefixlen 104 ::1 -reject >/dev/null 24503056e2eSderaadt route -qn add -inet6 ::0.0.0.0 -prefixlen 104 ::1 -reject >/dev/null 24603056e2eSderaadt route -qn add -inet6 ::255.0.0.0 -prefixlen 104 ::1 -reject >/dev/null 24792aceabbSitojun 248dfc209d0Smiod # Disallow packets to malicious 6to4 prefix. 24903056e2eSderaadt route -qn add -inet6 2002:e000:: -prefixlen 20 ::1 -reject >/dev/null 25003056e2eSderaadt route -qn add -inet6 2002:7f00:: -prefixlen 24 ::1 -reject >/dev/null 25103056e2eSderaadt route -qn add -inet6 2002:0000:: -prefixlen 24 ::1 -reject >/dev/null 25203056e2eSderaadt route -qn add -inet6 2002:ff00:: -prefixlen 24 ::1 -reject >/dev/null 25392aceabbSitojun 254a4ee3723Sitojun # Disallow packets without scope identifier. 255a4ee3723Sitojun route -qn add -inet6 ff01:: -prefixlen 16 ::1 -reject >/dev/null 256a4ee3723Sitojun route -qn add -inet6 ff02:: -prefixlen 16 ::1 -reject >/dev/null 257a4ee3723Sitojun 25892aceabbSitojun # Completely disallow packets to IPv4 compatible prefix. 259300d0407Srpe # 26092aceabbSitojun # This may conflict with RFC1933 under following circumstances: 26192aceabbSitojun # (1) An IPv6-only KAME node tries to originate packets to IPv4 2625e268fadSderaadt # compatible destination. The KAME node has no IPv4 compatible 26392aceabbSitojun # support. Under RFC1933, it should transmit native IPv6 26492aceabbSitojun # packets toward IPv4 compatible destination, hoping it would 26592aceabbSitojun # reach a router that forwards the packet toward auto-tunnel 26692aceabbSitojun # interface. 2675e268fadSderaadt # (2) An IPv6-only node originates a packet to an IPv4 compatible 26892aceabbSitojun # destination. A KAME node is acting as an IPv6 router, and 26992aceabbSitojun # asked to forward it. 270300d0407Srpe # 2715e268fadSderaadt # Due to rare use of IPv4 compatible addresses, and security issues 27292aceabbSitojun # with it, we disable it by default. 27303056e2eSderaadt route -qn add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject >/dev/null 27482c17b75Sitojun 27582c17b75Sitojun rtsolif="" 2763d8fed7cSitojunelse 2773d8fed7cSitojun ip6kernel=NO 2783d8fed7cSitojunfi 2793d8fed7cSitojun 280df930be7Sderaadt 2819ac6b043Stodd# Configure all the non-loopback interfaces which we know about, but 2824eb97611Sderaadt# do not start interfaces which must be delayed. Refer to hostname.if(5) 28329ae3f59Srzalamenaifmstart "" "trunk svlan vlan carp gif gre pfsync pppoe tun bridge switch pflow" 28482c17b75Sitojun 2854bdcd471Sbrad# The trunk interfaces need to come up first in this list. 286f45bd3bdSmpf# The (s)vlan interfaces need to come up after trunk. 2874bdcd471Sbrad# Configure all the carp interfaces which we know about before default route. 288f45bd3bdSmpfifmstart "trunk svlan vlan carp" 2894bdcd471Sbrad 2906125fd66Ssthen# Now that $rtsolif has been populated, IPv6 autoconf those interfaces 29193230e63Srpeifv6autoconf 29282c17b75Sitojun 29380819bdcStodd# Look for default routes in /etc/mygate. 29405102370Smpidefaultroute 295cf3860a5Sderaadt 296745634aaSniklas# Multicast routing. 2976e0f151eSsthenif [[ $multicast != YES ]]; then 298705fcffdSreyk route -qn delete 224.0.0.0/4 >/dev/null 2>&1 299f4b4b73bSderaadt route -qn add -net 224.0.0.0/4 -interface 127.0.0.1 -reject >/dev/null 3006e0f151eSsthenfi 301dfc209d0Smiod 302f002925aSflorian# Configure PPPoE, GIF, GRE, TUN and PFLOW interfaces, delayed because they 303f002925aSflorian# require routes to be set. TUN might depend on PPPoE, and GIF or GRE may 304f002925aSflorian# depend on either of them. PFLOW might bind to ip addresses configured 305f002925aSflorian# on either of them. 30629ae3f59Srzalamenaifmstart "pppoe tun gif gre bridge switch pflow" 307dfc209d0Smiod 308300d0407Srpe# Reject 127/8 other than 127.0.0.1. 3098f8fdbefSderaadtroute -qn add -net 127 127.0.0.1 -reject >/dev/null 3108f8fdbefSderaadt 3110a295e45Srpeif [[ $ip6kernel == YES ]]; then 312300d0407Srpe # This is to make sure DAD is completed before going further. 313c653ce7bSmarkus count=0 3140a295e45Srpe while ((count++ < 10 && $(sysctl -n net.inet6.ip6.dad_pending) != 0)); do 315c653ce7bSmarkus sleep 1 316c653ce7bSmarkus done 317089287c3Sdavidfi 318