rc.d: Add ip6addrctl (enabled by default with policy AUTO)
authorAaron LI <aly@aaronly.me>
Mon, 5 Nov 2018 20:25:17 +0000 (04:25 +0800)
committerAaron LI <aly@aaronly.me>
Mon, 5 Nov 2018 20:30:14 +0000 (04:30 +0800)
Bring in the ip6addrctl rc script from FreeBSD.  It is enabled by
default with policy "AUTO", so the IPv4/IP6 preference is configured on
startup.  The rc variable "ip6addrctl_policy" is used to adjust the
preference (AUTO, ipv6_prefer, ipv6_prefer).

See the rc.conf(5) man page for more details.

etc/defaults/rc.conf
etc/rc.d/Makefile
etc/rc.d/ip6addrctl [new file with mode: 0644]
share/man/man5/rc.conf.5

index 7d57c97..fd9d983 100644 (file)
@@ -1,5 +1,4 @@
 #!/bin/sh
-#
 
 # This is rc.conf - a file full of useful variables that you can set
 # to change the default startup behavior of your system.  You should
@@ -13,6 +12,9 @@
 #
 # All arguments must be in double or single quotes.
 #
+# For a more detailed explanation of all the rc.conf variables, please
+# refer to the rc.conf(5) manual page.
+#
 # $FreeBSD: src/etc/defaults/rc.conf,v 1.180 2003/06/26 09:50:50 smkelly Exp $
 
 ##############################################################
@@ -282,6 +284,10 @@ ipv6_firewall_type="UNKNOWN"       # IPv6 Firewall type (see /etc/rc.firewall6)
 ipv6_firewall_quiet="NO"       # Set to YES to suppress rule display
 ipv6_firewall_logging="NO"     # Set to YES to enable events logging
 ipv6_firewall_flags=""         # Flags passed to ip6fw when type is a file
+ip6addrctl_enable="YES"                # Set to YES to enable default address selection
+ip6addrctl_verbose="NO"                # Set to YES to enable verbose configuration messages
+ip6addrctl_policy="AUTO"       # A pre-defined address selection policy
+                               # (ipv4_prefer, ipv6_prefer, or AUTO)
 
 ##############################################################
 ###  System console options  #################################
index 55eca8a..9471e4b 100644 (file)
@@ -10,7 +10,7 @@ FILES=        DAEMON LOGIN NETWORKING SERVERS \
        bootconf bootparams btconfig bthcid ccd cleanvar cryptdisks \
        cleartmp cron cryptdisks devd devfs dhclient diskless dmesg dumpon \
        fixbootfile fsck ftpd hostname hotplugd \
-       inetd initdiskless initrandom ip6fw ipfw ipfw3 jail keyserv \
+       inetd initdiskless initrandom ip6addrctl ip6fw ipfw ipfw3 jail keyserv \
        ldconfig local localdaemons lockd lpd lvm \
        mixer modules motd mountcritlocal mountcritremote \
        mountd moused mroute6d mrouted msgs \
diff --git a/etc/rc.d/ip6addrctl b/etc/rc.d/ip6addrctl
new file mode 100644 (file)
index 0000000..7d51d48
--- /dev/null
@@ -0,0 +1,111 @@
+#!/bin/sh
+#
+# $FreeBSD: head/libexec/rc/rc.d/ip6addrctl 320802 2017-07-08 09:28:31Z kp $
+#
+
+# PROVIDE: ip6addrctl
+# REQUIRE: FILESYSTEMS
+# BEFORE: netif
+# KEYWORD: nojailvnet
+
+. /etc/rc.subr
+. /etc/network.subr
+
+name="ip6addrctl"
+desc="configure address selection policy for IPv6 and IPv4"
+rcvar="ip6addrctl_enable"
+start_cmd="ip6addrctl_start"
+stop_cmd="ip6addrctl_stop"
+extra_commands="status prefer_ipv6 prefer_ipv4"
+status_cmd="ip6addrctl"
+prefer_ipv6_cmd="ip6addrctl_prefer_ipv6"
+prefer_ipv4_cmd="ip6addrctl_prefer_ipv4"
+config_file="/etc/ip6addrctl.conf"
+
+IP6ADDRCTL_CMD="/usr/sbin/ip6addrctl"
+
+ip6addrctl_prefer_ipv6()
+{
+       afexists inet6 || return 0
+
+       ${IP6ADDRCTL_CMD} flush >/dev/null 2>&1
+       cat <<EOT | ${IP6ADDRCTL_CMD} install /dev/stdin
+       ::1/128          50      0
+       ::/0             40      1
+       ::ffff:0:0/96    35      4
+       2002::/16        30      2
+       2001::/32         5      5
+       fc00::/7          3     13
+       ::/96             1      3
+       fec0::/10         1     11
+       3ffe::/16         1     12
+EOT
+}
+
+ip6addrctl_prefer_ipv4()
+{
+       afexists inet6 || return 0
+
+       ${IP6ADDRCTL_CMD} flush >/dev/null 2>&1
+       cat <<EOT | ${IP6ADDRCTL_CMD} install /dev/stdin
+       ::1/128          50      0
+       ::/0             40      1
+       ::ffff:0:0/96   100      4
+       2002::/16        30      2
+       2001::/32         5      5
+       fc00::/7          3     13
+       ::/96             1      3
+       fec0::/10         1     11
+       3ffe::/16         1     12
+EOT
+}
+
+ip6addrctl_start()
+{
+       afexists inet6 || return 0
+
+       # Install the policy of the address selection algorithm.
+       case "${ip6addrctl_policy}" in
+       [Aa][Uu][Tt][Oo])
+               if [ -r "${config_file}" -a -s "${config_file}" ]; then
+                       ${IP6ADDRCTL_CMD} flush >/dev/null 2>&1
+                       ${IP6ADDRCTL_CMD} install "${config_file}"
+               else
+                       if checkyesno ipv6_enable; then
+                               ip6addrctl_prefer_ipv6
+                       else
+                               ip6addrctl_prefer_ipv4
+                       fi
+               fi
+               ;;
+       ipv4_prefer)
+               ip6addrctl_prefer_ipv4
+               ;;
+       ipv6_prefer)
+               ip6addrctl_prefer_ipv6
+               ;;
+       [Nn][Oo][Nn][Ee])
+               ${IP6ADDRCTL_CMD} flush >/dev/null 2>&1
+               ;;
+       *)
+               warn "\$ip6addrctl_policy is invalid: ${ip6addrctl_policy}. " \
+                   " \"ipv4_prefer\" is used instead."
+               ip6addrctl_prefer_ipv4
+               ;;
+       esac
+
+       if checkyesno ip6addrctl_verbose; then
+               echo 'Address selection policy table for IPv4 and IPv6:'
+               ${IP6ADDRCTL_CMD}
+       fi
+}
+
+ip6addrctl_stop()
+{
+       afexists inet6 || return 0
+
+       ip6addrctl flush >/dev/null 2>&1
+}
+
+load_rc_config $name
+run_rc_command "$1"
index a3d0ea0..1d12438 100644 (file)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD: src/share/man/man5/rc.conf.5,v 1.197 2003/07/28 13:56:00 mbr Exp $
 .\"
-.Dd October 23, 2018
+.Dd November 6, 2018
 .Dt RC.CONF 5
 .Os
 .Sh NAME
@@ -844,6 +844,57 @@ If not set to
 .Dq Li NO ,
 this is the default output interface for scoped addresses.
 Now this works only for IPv6 link local multicast addresses.
+.It Va ip6addrctl_enable
+.Pq Vt bool
+This variable is to enable configuring default address selection policy table
+.Pq RFC 3484 .
+The table can be specified in another variable
+.Va ip6addrctl_policy .
+For
+.Va ip6addrctl_policy
+the following keywords can be specified:
+.Dq Li ipv4_prefer ,
+.Dq Li ipv6_prefer ,
+or
+.Dq Li AUTO .
+.Pp
+If
+.Dq Li ipv4_prefer
+or
+.Dq Li ipv6_prefer
+is specified,
+.Xr ip6addrctl 8
+installs a pre-defined policy table described in Section 2.1
+.Pq IPv6-preferred
+or 10.3
+.Pq IPv4-preferred
+of RFC 3484.
+.Pp
+If
+.Dq Li AUTO
+is specified, it attempts to read a file
+.Pa /etc/ip6addrctl.conf
+first.
+If this file is found,
+.Xr ip6addrctl 8
+reads and installs it.
+If not found, a policy is automatically set
+according to
+.Va ipv6_enable
+variable; if the variable is set to
+.Dq Li YES
+the IPv6-preferred one is used.
+Otherwise IPv4-preferred.
+.Pp
+The default value of
+.Va ip6addrctl_enable
+and
+.Va ip6addrctl_policy
+are
+.Dq Li YES
+and
+.Dq Li AUTO ,
+respectively.
 .It Va cloned_interfaces
 .Pq Vt str
 Set to the list of clonable network interfaces to create on this host.
@@ -2670,6 +2721,7 @@ By default no flags are passed.
 .Xr ftpd 8 ,
 .Xr ifconfig 8 ,
 .Xr inetd 8 ,
+.Xr ip6addrctl 8 ,
 .Xr jail 8 ,
 .Xr lpd 8 ,
 .Xr makewhatis 8 ,