1 #!/sbin/sh
   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 #
  23 # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  24 #
  25 # Copyright (c) 2012 Joyent, Inc.  All rights reserved.
  26 
  27 # This script configures IP routing.
  28 
  29 . /lib/svc/share/smf_include.sh
  30 
  31 set -o xtrace
  32 
  33 #
  34 # In a shared-IP zone we need this service to be up, but all of the work
  35 # it tries to do is irrelevant (and will actually lead to the service 
  36 # failing if we try to do it), so just bail out. 
  37 # In the global zone and exclusive-IP zones we proceed.
  38 #
  39 smf_configure_ip || exit $SMF_EXIT_OK
  40 
  41 #
  42 # If routing.conf file is in place, and has not already been read in
  43 # by previous invokation of routeadm, legacy configuration is upgraded
  44 # by this call to "routeadm -u".  This call is also needed when
  45 # a /var/svc/profile/upgrade file is found, as it may contain routeadm commands
  46 # which need to be applied.  Finally, routeadm starts in.ndpd by
  47 # enabling the ndp service (in.ndpd), which is required for IPv6 address
  48 # autoconfiguration. It would be nice if we could do this in
  49 # network/loopback, but since the SMF backend is read-only at that
  50 # point in boot, we cannot.
  51 #
  52 /sbin/routeadm -u
  53 
  54 #
  55 # Are we routing dynamically? routeadm(1M) reports this in the
  56 # "current" values of ipv4/6-routing - if either are true, we are running
  57 # routing daemons (or at least they are enabled to run).
  58 #
  59 dynamic_routing_test=`/sbin/routeadm -p | \
  60 nawk '/^ipv[46]-routing [.]*/ { print $2 }'  | /usr/bin/grep "current=enabled"`
  61 if [ -n "$dynamic_routing_test" ]; then
  62         dynamic_routing="true"
  63 fi
  64 
  65 #
  66 # Configure default IPv4 routers using the local "/etc/defaultrouter"
  67 # configuration file.  The file can contain the hostnames or IP
  68 # addresses of one or more default routers.  If hostnames are used,
  69 # each hostname must also be listed in the local "/etc/hosts" file
  70 # because NIS is not running at the time that this script is
  71 # run.  Each router name or address is listed on a single line by
  72 # itself in the file.  Anything else on that line after the router's
  73 # name or address is ignored.  Lines that begin with "#" are
  74 # considered comments and ignored.
  75 #
  76 # The default routes listed in the "/etc/defaultrouter" file will
  77 # replace those added by the kernel during diskless booting.  An
  78 # empty "/etc/defaultrouter" file will cause the default route
  79 # added by the kernel to be deleted.
  80 #
  81 # Note that the default router file is ignored if we received routes
  82 # from a DHCP server.  Our policy is to always trust DHCP over local
  83 # administration.
  84 #
  85 smf_netstrategy
  86 
  87 #
  88 # Read /etc/inet/static_routes.vmadm and add each route.
  89 #
  90 if [ -f /etc/inet/static_routes.vmadm ]; then
  91         echo "Adding vmadm persistent link-local routes:"
  92         /usr/bin/egrep -v "^(#|$)"  /etc/inet/static_routes.vmadm | /usr/bin/egrep -e "-interface " | while read line; do
  93                 /usr/sbin/route add $line
  94         done
  95 fi
  96 
  97 if [ "$_INIT_NET_STRATEGY" = "dhcp" ] && \
  98     [ -n "`/sbin/dhcpinfo Router`" ]; then
  99         defrouters=`/sbin/dhcpinfo Router`
 100 elif [ -f /etc/defaultrouter ]; then
 101         defrouters=`/usr/bin/grep -v \^\# /etc/defaultrouter | \
 102             /usr/bin/awk '{print $1}'`
 103         if [ -n "$defrouters" ]; then
 104                 #
 105                 # We want the default router(s) listed in
 106                 # /etc/defaultrouter to replace the one added from the
 107                 # BOOTPARAMS WHOAMI response but we must avoid flushing
 108                 # the last route between the running system and its
 109                 # /usr file system.
 110                 #
 111 
 112                 # First, remember the original route.
 113                 shift $#
 114                 set -- `/usr/bin/netstat -rn -f inet | \
 115                     /usr/bin/grep '^default'`
 116                 route_IP="$2"
 117 
 118                 #
 119                 # Next, add those from /etc/defaultrouter.  While doing
 120                 # this, if one of the routes we add is for the route
 121                 # previously added as a result of the BOOTPARAMS
 122                 # response, we will see a message of the form:
 123                 #       "add net default: gateway a.b.c.d: entry exists"
 124                 #
 125                 do_delete=yes
 126                 for router in $defrouters; do
 127                         route_added=`/usr/sbin/route -n add default \
 128                             -gateway $router`
 129                         res=$?
 130                         set -- $route_added
 131                         [ $res -ne 0 -a "$5" = "$route_IP:" ] && do_delete=no
 132                 done
 133 
 134                 #
 135                 # Finally, delete the original default route unless it
 136                 # was also listed in the defaultrouter file.
 137                 #
 138                 if [ -n "$route_IP" -a $do_delete = yes ]; then
 139                         /usr/sbin/route -n delete default \
 140                             -gateway $route_IP >/dev/null
 141                 fi
 142         else
 143                 /usr/sbin/route -fn > /dev/null
 144         fi
 145 else
 146         defrouters=
 147 fi
 148 
 149 #
 150 # Use routeadm(1M) to configure forwarding and launch routing daemons
 151 # for IPv4 and IPv6 based on preset values.  These settings only apply
 152 # to the global zone.  For IPv4 dynamic routing, the system will default
 153 # to disabled if a default route was previously added via BOOTP, DHCP,
 154 # or the /etc/defaultrouter file.  routeadm also starts in.ndpd.
 155 #
 156 if [ "$dynamic_routing" != "true"  ] && [ -z "$defrouters" ]; then
 157         #
 158         # No default routes were setup by "route" command above.
 159         # Check the kernel routing table for any other default
 160         # routes.
 161         #
 162         /usr/bin/netstat -rn -f inet | \
 163             /usr/bin/grep default >/dev/null 2>&1 && defrouters=yes
 164 fi
 165 
 166 #
 167 # The routeadm/ipv4-routing-set property is true if the administrator
 168 # has run "routeadm -e/-d ipv4-routing".  If not, we revert to the
 169 # appropriate defaults.  We no longer run "routeadm -u" on every boot
 170 # however, as persistent daemon state is now controlled by SMF.
 171 #
 172 ipv4_routing_set=`/usr/bin/svcprop -p routeadm/ipv4-routing-set $SMF_FMRI`
 173 smartos_param=`/usr/bin/bootparams | grep "^smartos"`
 174 if [ -z "$defrouters" ] && [ "$smartos_param" != "" ]; then
 175         #
 176         # Set default value for ipv4-routing to enabled.  If routeadm -e/-d
 177         # has not yet been run by the administrator, we apply this default.
 178         # The -b option is project-private and informs routeadm not
 179         # to treat the enable as administrator-driven.
 180         #
 181         /usr/sbin/svccfg -s $SMF_FMRI \
 182             setprop routeadm/default-ipv4-routing = true
 183         if [ "$ipv4_routing_set" = "false" ]; then
 184                 /sbin/routeadm -b -e ipv4-routing -u
 185         fi
 186 else
 187         #
 188         # Default router(s) have been found,  so ipv4-routing default value
 189         # should be disabled.  If routaedm -e/d has not yet been run by
 190         # the administrator, we apply this default.  The -b option is
 191         # project-private and informs routeadm not to treat the disable as
 192         # administrator-driven.
 193         #
 194         /usr/sbin/svccfg -s $SMF_FMRI \
 195             setprop routeadm/default-ipv4-routing = false
 196         if [ "$ipv4_routing_set" = "false" ]; then
 197                 /sbin/routeadm -b -d ipv4-routing -u
 198         fi
 199 fi
 200 
 201 #
 202 # See if static routes were created by install. If so, they were created
 203 # under /etc/svc/volatile. Copy them into their proper place.
 204 #
 205 if [ -f /etc/svc/volatile/etc/inet/static_routes ]; then
 206         echo "Installing persistent routes"
 207         if [ -f /etc/inet/static_routes ]; then
 208                 cat /etc/svc/volatile/etc/inet/static_routes | grep -v '^#' \
 209                     >> /etc/inet/static_routes
 210         else
 211                 cp /etc/svc/volatile/etc/inet/static_routes \
 212                     /etc/inet/static_routes
 213         fi
 214         /usr/bin/rm /etc/svc/volatile/etc/inet/static_routes
 215         
 216 fi
 217 
 218 #
 219 # Read /etc/inet/static_routes and add each route.
 220 #
 221 if [ -f /etc/inet/static_routes ]; then
 222         echo "Adding persistent routes:"
 223         /usr/bin/egrep -v "^(#|$)" /etc/inet/static_routes | while read line; do
 224                 /usr/sbin/route add $line
 225         done
 226 fi
 227 
 228 #
 229 # Read /etc/inet/static_routes.vmadm and add each non-link-local route.
 230 #
 231 if [ -f /etc/inet/static_routes.vmadm ]; then
 232         echo "Adding vmadm persistent routes:"
 233         /usr/bin/egrep -v "^(#|$)" /etc/inet/static_routes.vmadm | /usr/bin/egrep -v -e "-interface " | while read line; do
 234                 /usr/sbin/route add $line
 235         done
 236 fi
 237 
 238 #
 239 # Log the result
 240 #
 241 echo "Routing setup complete:"
 242 /usr/bin/netstat -rn
 243 
 244 # Clear exit status.
 245 exit $SMF_EXIT_OK