From 0686fd92529ce07dcb7e11b6dfe0710760040ac0 Mon Sep 17 00:00:00 2001 From: Olivier Mehani Date: Tue, 16 Mar 2010 15:32:58 +1100 Subject: [PATCH 2/3] IPv6 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following options are added: - IP6: - none: deactivate autoconfiguration and don't do anything else - stateless: “normal” autoconfiguration - dhcp: use “dhclient -6” - dhcp-noaddr: use “dhclient -6 -S” and stateless autoconfiguration - static: configure $INTERFACE with $ADDR6/$PREFIXLEN * 'dhcp' and 'static' also deactivate stateless autoconfiguration; it is reactivated in any case when the interface is brought down to restore a “neutral” situation - GATEWAY6, IP6CFG: similar to their IPv4 counterparts except the commands are run ith “ip -6” Both DHCPv6 options also use variable DHCLIENT6_OPTIONS for further configuration IFOPTS is used for both IPv4 and IPv6, and only if the interface is not already up. Potential bug: The relationship of the net.ipv6.conf.*.accept_ra sysctl values is not straigthforward nor well documented. According to scarce information [0,1,2], it would seem that: - net.ipv6.conf.default.accept_ra is used to initialise new interfaces, - net.ipv6.conf.INTERFACE.accept_ra controls the actual value BUT - net.ipv6.conf.all.accept_ra is combined with the previous value before any decision is applied to the interface. Now, “combined” seems to take a varying meaning depending on the parameter under consideration [0, 2]. I couldn't dedicate much time to crawling the kernel source, so I did some tests instead. My tentative conclusion is that net.ipv6.conf.all.accept_ra is ORed with net.ipv6.conf.INTERFACE.accept_ra. So, to really ignore RAs, both these settings have to be set to 0. [0] http://marc.info/?l=linux-kernel&m=123606366021995&w=2 [1] http://lkml.indiana.edu/hypermail/linux/kernel/0103.0/0440.html [2] http://marc.info/?l=linux-kernel&m=123617372002934&w=2 Signed-off-by: Olivier Mehani --- src/connections/ethernet | 89 ++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 82 insertions(+), 7 deletions(-) diff --git a/src/connections/ethernet b/src/connections/ethernet index bdc311d..c97aa18 100644 --- a/src/connections/ethernet +++ b/src/connections/ethernet @@ -46,6 +46,11 @@ ethernet_up() { fi fi + if [[ -z "$IP" && -z "$IP6" && "$IP6" != "none" ]]; then + report_iproute "At least one of IP or IP6 should be specified and not 'none'" + return 1 + fi + case "$IP" in dhcp) if checkyesno "${DHCLIENT:-no}"; then @@ -77,12 +82,7 @@ ethernet_up() { report_iproute "Could not configure interface" fi fi - if [[ -n "$IFOPTS" ]]; then - if ! ifconfig "$INTERFACE" $IFOPTS up; then - report_iproute "Bringing interface up failed." - return 1 - fi - fi + ethernet_dev_up if [[ -n "$GATEWAY" ]]; then report_debug ethernet_iproute_up ip route add default via "$GATEWAY" if ! ip route add default via "$GATEWAY"; then @@ -90,6 +90,8 @@ ethernet_up() { fi fi ;; + "") + ;; *) report_iproute "IP must be either 'dhcp' or 'static'" ;; @@ -105,7 +107,7 @@ ethernet_up() { done fi - if [[ -n "$IPCFG" ]]; then + if [[ -n "$IPCFG" && ! -z "$IP" ]]; then for line in "${IPCFG[@]}"; do report_debug ethernet_iproute_up ip "$line" @@ -115,6 +117,67 @@ ethernet_up() { done fi + case "$IP6" in + none) + sysctl -q -w net.ipv6.conf.$INTERFACE.accept_ra=0 + ethernet_dev_up + ;; + stateless) + sysctl -q -w net.ipv6.conf.$INTERFACE.accept_ra=1 + ethernet_dev_up + ;; + dhcp*) + if [[ -x /usr/sbin/dhclient ]]; then + if [[ "$IP6" = "dhcp-noaddr" ]]; then + sysctl -q -w net.ipv6.conf.$INTERFACE.accept_ra=1 + DHCLIENT6_OPTIONS="-S ${DHCLIENT6_OPTIONS}" + else + sysctl -q -w net.ipv6.conf.$INTERFACE.accept_ra=0 + fi + rm -r "/var/run/dhclient-${INTERFACE}-v6.pid" >/dev/null 2>&1 + report_debug ethernet_up dhclient -6 -q -e TIMEOUT="${DHCP_TIMEOUT:-10}" -pf "/var/run/dhclient-$INTERFACE-v6.pid" "$INTERFACE" + if ! dhclient -6 -q -e TIMEOUT="${DHCP_TIMEOUT:-10}" -pf "/var/run/dhclient-${INTERFACE}-v6.pid" ${DHCLIENT6_OPTIONS} "$INTERFACE"; then + report_fail "DHCPv6 IP lease attempt failed." + return 1 + fi + else + report_fail "DHCPv6 usage needs extra/dhclient." + fi + ;; + static) + if [[ -n "$ADDR6" ]]; then + [[ -z $PREFIXLEN ]] && PREFIXLEN=64 + report_debug ethernet_iproute_up ip -6 addr add "$ADDR6/$PREFIXLEN" dev "$INTERFACE" + if ! ip -6 addr add "$ADDR6/$PREFIXLEN" dev "$INTERFACE"; then + report_iproute "Could not configure interface" + fi + sysctl -q -w net.ipv6.conf.$INTERFACE.accept_ra=0 + fi + ethernet_dev_up + if [[ -n "$GATEWAY6" ]]; then + report_debug ethernet_iproute_up ip -6 route add default via "$GATEWAY6" + if ! ip -6 route add default via "$GATEWAY6"; then + report_iproute "Adding gateway $GATEWAY6 failed" + fi + fi + ;; + "") + ;; + *) + report_iproute "IP6 must be 'none', 'stateless', 'dhcp', 'dhcp-noaddr', or 'static'" + ;; + esac + + if [[ -n "$IP6CFG" && ! -z "$IP6" && "$IP6" != "none" ]]; then + for line in "${IP6CFG[@]}"; do + + report_debug ethernet_iproute_up ip -6 "$line" + if ! ip -6 $line; then + report_iproute "Could not configure interface ($line)." + fi + done + fi + # Set hostname if [[ -n "$HOSTNAME" ]]; then report_debug ethernet_iproute_up hostname "$HOSTNAME" @@ -143,6 +206,15 @@ ethernet_up() { return 0 } +ethernet_dev_up() { + if [[ -n "$IFOPTS" && ! ethernet_status ]]; then + if ! ifconfig "$INTERFACE" $IFOPTS up; then + report_iproute "Bringing interface up failed." + return 1 + fi + fi +} + ethernet_down() { load_profile "$1" @@ -151,6 +223,9 @@ ethernet_down() { report_debug ethernet_down dhcpcd -qx "$INTERFACE" dhcpcd -qx "$INTERFACE" &>/dev/null fi + fi + if [[ ! -z "$IP6" ]]; then + sysctl -q -w net.ipv6.conf.$INTERFACE.accept_ra=1 fi report_debug ethernet_down if_down -- 1.7.0.2