Author: hrs
Date: Fri Jul 12 01:34:24 2013
New Revision: 253238
URL: http://svnweb.freebsd.org/changeset/base/253238

Log:
  MFC 251584:
  
  Add :ifname modifier to specify interface-specific routes into
  {,ipv6_}static_routes and rc.d/routing.  For example:
  
   static_routes="foo bar:em0"
   route_foo="-net 10.0.0.0/24 -gateway 192.168.2.1"
   route_bar="-net 192.168.1.0/24 -gateway 192.168.0.2"
  
  At boot time, all of the static routes are installed as before.
  The differences are:
  
  - "/etc/rc.d/netif start/stop <if>" now configures static routes
    with :<if> if any.
  - "/etc/rc.d/routing start/stop <af> <if>" works as well.  <af> cannot be
    omitted when <if> is specified, but a keyword "any" or "all" can be used
    for <af> and <if>.

Modified:
  stable/9/etc/rc.d/netif
  stable/9/etc/rc.d/routing
  stable/9/share/man/man5/rc.conf.5
Directory Properties:
  stable/9/etc/rc.d/   (props changed)
  stable/9/share/man/man5/   (props changed)

Modified: stable/9/etc/rc.d/netif
==============================================================================
--- stable/9/etc/rc.d/netif     Fri Jul 12 01:29:57 2013        (r253237)
+++ stable/9/etc/rc.d/netif     Fri Jul 12 01:34:24 2013        (r253238)
@@ -46,6 +46,8 @@ set_rcvar_obsolete ipv6_prefer
 
 network_start()
 {
+       local _if
+
        # Set the list of interfaces to work on.
        #
        cmdifn=$*
@@ -81,16 +83,29 @@ network_start()
        if [ -f /etc/rc.d/bridge -a -n "$cmdifn" ] ; then
                /etc/rc.d/bridge start $cmdifn
        fi
+       if [ -f /etc/rc.d/routing -a -n "$cmdifn" ] ; then
+               for _if in $cmdifn; do
+                       /etc/rc.d/routing start any $_if
+               done
+       fi
 }
 
 network_stop()
 {
+       local _if
+
        # Set the list of interfaces to work on.
        #
        cmdifn=$*
 
        # Deconfigure the interface(s)
        network_common ifn_stop
+
+       if [ -f /etc/rc.d/routing -a -n "$cmdifn" ] ; then
+               for _if in $cmdifn; do
+                       /etc/rc.d/routing stop any $_if
+               done
+       fi
 }
 
 # network_common routine

Modified: stable/9/etc/rc.d/routing
==============================================================================
--- stable/9/etc/rc.d/routing   Fri Jul 12 01:29:57 2013        (r253237)
+++ stable/9/etc/rc.d/routing   Fri Jul 12 01:34:24 2013        (r253238)
@@ -19,56 +19,73 @@ extra_commands="options static"
 static_cmd="routing_start static"
 options_cmd="routing_start options"
 
-afcheck()
-{
-       case $_af in
-       ""|inet|inet6|ipx|atm)
-               ;;
-       *)
-               err 1 "Unsupported address family: $_af."
-               ;;
-       esac
-}
+ROUTE_CMD="/sbin/route"
 
 routing_start()
 {
-       local _cmd _af _a
+       local _cmd _af _if _a
        _cmd=$1
        _af=$2
+       _if=$3
 
-       afcheck
+       case $_if in
+       ""|[Aa][Ll][Ll]|[Aa][Nn][Yy])   _if="" ;;
+       esac
 
        case $_af in
        inet|inet6|ipx|atm)
-               setroutes $_cmd $_af
+               if afexists $_af; then
+                       setroutes $_cmd $_af $_if
+               else
+                       err 1 "Unsupported address family: $_af."
+               fi
                ;;
-       "")
+       ""|[Aa][Ll][Ll]|[Aa][Nn][Yy])
                for _a in inet inet6 ipx atm; do
-                       afexists $_a && setroutes $_cmd $_a
+                       afexists $_a && setroutes $_cmd $_a $_if
                done
                ;;
+       *)
+               err 1 "Unsupported address family: $_af."
+               ;;
        esac
 }
 
 routing_stop()
 {
-       local _af _a
+       local _af _if _a
        _af=$1
+       _if=$2
 
-       afcheck
+       case $_if in
+       ""|[Aa][Ll][Ll]|[Aa][Nn][Yy])   _if="" ;;
+       esac
 
        case $_af in
        inet|inet6|ipx|atm)
-               eval static_${_af} delete
-               eval routing_stop_${_af}
+               if afexists $_af; then
+                       eval static_${_af} delete $_if 
+                       # When $_if is specified, do not flush routes.
+                       if ! [ -n "$_if" ]; then
+                               eval routing_stop_${_af}
+                       fi
+               else
+                       err 1 "Unsupported address family: $_af."
+               fi
                ;;
-       "")
+       ""|[Aa][Ll][Ll]|[Aa][Nn][Yy])
                for _a in inet inet6 ipx atm; do
                        afexists $_a || continue
-                       eval static_${_a} delete
-                       eval routing_stop_${_a}
+                       eval static_${_a} delete $_if
+                       # When $_if is specified, do not flush routes.
+                       if ! [ -n "$_if" ]; then
+                               eval routing_stop_${_a}
+                       fi
                done
                ;;
+       *)
+               err 1 "Unsupported address family: $_af."
+               ;;
        esac
 }
 
@@ -76,13 +93,13 @@ setroutes()
 {
        case $1 in
        static)
-               static_$2 add
+               static_$2 add $3
                ;;
        options)
                options_$2
                ;;
        doall)
-               static_$2 add
+               static_$2 add $3
                options_$2
                ;;
        esac
@@ -90,14 +107,14 @@ setroutes()
 
 routing_stop_inet()
 {
-       route -n flush -inet
+       ${ROUTE_CMD} -n flush -inet
 }
 
 routing_stop_inet6()
 {
        local i
 
-       route -n flush -inet6
+       ${ROUTE_CMD} -n flush -inet6
        for i in ${ipv6_network_interfaces}; do
                ifconfig $i inet6 -defaultif
        done
@@ -115,30 +132,47 @@ routing_stop_ipx()
 
 static_inet()
 {
-       local _action
+       local _action _if _skip
        _action=$1
+       _if=$2
 
+       # Add default route.
        case ${defaultrouter} in
        [Nn][Oo] | '')
                ;;
        *)
-               static_routes="default ${static_routes}"
-               route_default="default ${defaultrouter}"
+               static_routes="_default ${static_routes}"
+               route__default="default ${defaultrouter}"
                ;;
        esac
 
+       # Install configured routes.
        if [ -n "${static_routes}" ]; then
                for i in ${static_routes}; do
-                       route_args=`get_if_var $i route_IF`
-                       route ${_action} ${route_args}
+                       _skip=0
+                       if [ -n "$_if" ]; then
+                               case $i in
+                               *:$_if) ;;
+                               *)      _skip=1 ;;
+                               esac
+                       fi
+                       if [ $_skip = 0 ]; then
+                               route_args=`get_if_var ${i%:*} route_IF`
+                               if [ -n "$route_args" ]; then
+                                       ${ROUTE_CMD} ${_action} ${route_args}
+                               else
+                                       warn "route_${i%:*} not found."
+                               fi
+                       fi
                done
        fi
 }
 
 static_inet6()
 {
-       local _action fibmod fibs
+       local _action _if _skip fibmod fibs
        _action=$1
+       _if=$2
 
        # get the number of FIBs supported.
        fibs=$((`${SYSCTL_N} net.fibs` - 1))
@@ -148,58 +182,74 @@ static_inet6()
                fibmod=
        fi
 
+       # Add pre-defined static routes first.
+       ipv6_static_routes="_v4mapped _v4compat ${ipv6_static_routes}"
+       ipv6_static_routes="_lla _llma ${ipv6_static_routes}"
+
        # disallow "internal" addresses to appear on the wire
-       route ${_action} -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject 
${fibmod}
-       route ${_action} -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}
+       ipv6_route__v4mapped="::ffff:0.0.0.0 -prefixlen 96 ::1 -reject 
${fibmod}"
+       ipv6_route__v4compat="::0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}"
 
+       # Disallow link-local unicast packets without outgoing scope
+       # identifiers.  However, if you set "ipv6_default_interface",
+       # for the host case, you will allow to omit the identifiers.
+       # Under this configuration, the packets will go to the default
+       # interface.
+       ipv6_route__lla="fe80:: -prefixlen 10 ::1 -reject ${fibmod}"
+       ipv6_route__llma="ff02:: -prefixlen 16 ::1 -reject ${fibmod}"
+
+       # Add default route.
        case ${ipv6_defaultrouter} in
        [Nn][Oo] | '')
                ;;
        *)
-               ipv6_static_routes="default ${ipv6_static_routes}"
-               ipv6_route_default="default ${ipv6_defaultrouter}"
+               ipv6_static_routes="_default ${ipv6_static_routes}"
+               ipv6_route__default="default ${ipv6_defaultrouter}"
                ;;
        esac
 
+       # Install configured routes.
        if [ -n "${ipv6_static_routes}" ]; then
                for i in ${ipv6_static_routes}; do
-                       ipv6_route_args=`get_if_var $i ipv6_route_IF`
-                       route ${_action} -inet6 ${ipv6_route_args}
+                       _skip=0
+                       if [ -n "$_if" ]; then
+                               case $i in
+                               *:$_if) ;;
+                               *)      _skip=1 ;;
+                               esac
+                       fi
+                       if [ $_skip = 0 ]; then
+                               ipv6_route_args=`get_if_var ${i%:*} 
ipv6_route_IF`
+                               if [ -n "$ipv6_route_args" ]; then
+                                       ${ROUTE_CMD} ${_action} \
+                                               -inet6 ${ipv6_route_args}
+                               else
+                                       warn "route_${i%:*} not found"
+                               fi
+                       fi
                done
        fi
 
-       # Fixup $ipv6_network_interfaces
-       case ${ipv6_network_interfaces} in
-       [Nn][Oo][Nn][Ee])
-               ipv6_network_interfaces=''
-               ;;
-       esac
+       # Install the "default interface" to kernel, which will be used
+       # as the default route when there's no router.
 
+       # Disable installing the default interface when we act
+       # as router to avoid conflict between the default
+       # router list and the manual configured default route.
        if checkyesno ipv6_gateway_enable; then
-               for i in ${ipv6_network_interfaces}; do
-
-                       laddr=`network6_getladdr $i exclude_tentative`
-                       case ${laddr} in
-                       '')
-                               ;;
-                       *)
-                               ipv6_working_interfaces="$i \
-                                   ${ipv6_working_interfaces}"
-                               ;;
-                       esac
-               done
-               ipv6_network_interfaces=${ipv6_working_interfaces}
+               return
        fi
 
-       # Install the "default interface" to kernel, which will be used
-       # as the default route when there's no router.
        case "${ipv6_default_interface}" in
        [Nn][Oo] | [Nn][Oo][Nn][Ee])
-               ipv6_default_interface=""
+               return
                ;;
        [Aa][Uu][Tt][Oo] | "")
                for i in ${ipv6_network_interfaces}; do
                        case $i in
+                       [Nn][Oo][Nn][Ee])
+                               return
+                               ;;
                        lo0|faith[0-9]*)
                                continue
                                ;;
@@ -217,27 +267,8 @@ static_inet6()
                ;;
        esac
 
-       # Disallow link-local unicast packets without outgoing scope
-       # identifiers.  However, if you set "ipv6_default_interface",
-       # for the host case, you will allow to omit the identifiers.
-       # Under this configuration, the packets will go to the default
-       # interface.
-       route ${_action} -inet6 fe80:: -prefixlen 10 ::1 -reject ${fibmod}
-       route ${_action} -inet6 ff02:: -prefixlen 16 ::1 -reject ${fibmod}
-
-       case ${ipv6_default_interface} in
-       '')
-               ;;
-       *)
-               # Disable installing the default interface when we act
-               # as router to avoid conflict between the default
-               # router list and the manual configured default route.
-               if ! checkyesno ipv6_gateway_enable; then
-                       ifconfig ${ipv6_default_interface} inet6 defaultif
-                       sysctl net.inet6.ip6.use_defaultzone=1
-               fi
-               ;;
-       esac
+       ifconfig ${ipv6_default_interface} inet6 defaultif
+       sysctl net.inet6.ip6.use_defaultzone=1
 }
 
 static_atm()
@@ -248,7 +279,11 @@ static_atm()
        if [ -n "${natm_static_routes}" ]; then
                for i in ${natm_static_routes}; do
                        route_args=`get_if_var $i route_IF`
-                       atmconfig natm ${_action} ${route_args}
+                       if [ -n "$route_args" ]; then
+                               atmconfig natm ${_action} ${route_args}
+                       else
+                               warn "route_${i} not found."
+                       fi
                done
        fi
 }

Modified: stable/9/share/man/man5/rc.conf.5
==============================================================================
--- stable/9/share/man/man5/rc.conf.5   Fri Jul 12 01:29:57 2013        
(r253237)
+++ stable/9/share/man/man5/rc.conf.5   Fri Jul 12 01:34:24 2013        
(r253238)
@@ -2704,10 +2704,18 @@ whose contents will later be passed to a
 operation.
 For example:
 .Bd -literal
-static_routes="mcast gif0local"
+static_routes="ext mcast:gif0 gif0local:gif0"
+route_ext="-net 10.0.0.0/24 -gateway 192.168.0.1"
 route_mcast="-net 224.0.0.0/4 -iface gif0"
 route_gif0local="-host 169.254.1.1 -iface lo0"
 .Ed
+.Pp
+When an
+.Ar element
+is in the form of
+.Li name:ifname ,
+the route is specific to the interface
+.Li ifname .
 .It Va ipv6_static_routes
 .Pq Vt str
 The IPv6 equivalent of
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to