From 3b86e2508b13f4bd6339f7be708a2cf1eab99a44 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Wed, 11 Jul 2001 05:23:56 +0000 Subject: big ipv6 update from Pekka Savola () --- initscripts.spec | 8 +- ipv6-6to4.howto | 120 +++ ipv6-tunnel.howto | 25 +- ppp/ip-down.ipv6to4 | 105 +++ ppp/ip-up.ipv6to4 | 160 ++++ rc.d/init.d/network | 27 + sysconfig.txt | 71 +- sysconfig/network-scripts/ifdown | 2 +- sysconfig/network-scripts/ifdown-ipv6 | 106 ++- sysconfig/network-scripts/ifdown-sit | 77 +- sysconfig/network-scripts/ifup | 7 +- sysconfig/network-scripts/ifup-ipv6 | 221 +++++- sysconfig/network-scripts/ifup-sit | 67 +- sysconfig/network-scripts/init.ipv6-global | 188 +++++ sysconfig/network-scripts/network-functions-ipv6 | 971 ++++++++++++++++------- 15 files changed, 1760 insertions(+), 395 deletions(-) create mode 100644 ipv6-6to4.howto create mode 100644 ppp/ip-down.ipv6to4 create mode 100644 ppp/ip-up.ipv6to4 create mode 100755 sysconfig/network-scripts/init.ipv6-global diff --git a/initscripts.spec b/initscripts.spec index 8bb6987c..8818c7ab 100644 --- a/initscripts.spec +++ b/initscripts.spec @@ -1,6 +1,6 @@ Summary: The inittab file and the /etc/init.d scripts. Name: initscripts -Version: 6.01 +Version: 6.02 License: GPL Group: System Environment/Base Release: 1 @@ -167,6 +167,7 @@ rm -rf $RPM_BUILD_ROOT %config(noreplace) /etc/sysconfig/rawdevices %config /etc/sysconfig/network-scripts/network-functions %config /etc/sysconfig/network-scripts/network-functions-ipv6 +%config /etc/sysconfig/network-scripts/init.ipv6-global %config /etc/sysconfig/network-scripts/ifcfg-lo %config /etc/sysconfig/network-scripts/ifup-post %config /etc/sysconfig/network-scripts/ifdown-ppp @@ -225,8 +226,10 @@ rm -rf $RPM_BUILD_ROOT %dir %attr(775,root,root) /var/run/netreport %config /etc/ppp/ip-up %config /etc/ppp/ip-down +%config /etc/ppp/ip-up.ipv6to4 +%config /etc/ppp/ip-down.ipv6to4 %config /etc/initlog.conf -%doc sysconfig.txt sysvinitfiles ChangeLog static-routes-ipv6 ipv6-tunnel.howto +%doc sysconfig.txt sysvinitfiles ChangeLog static-routes-ipv6 ipv6-tunnel.howto ipv6-6to4.howto %ghost %attr(0664,root,utmp) /var/log/wtmp %ghost %attr(0664,root,utmp) /var/run/utmp @@ -237,6 +240,7 @@ rm -rf $RPM_BUILD_ROOT - fix some invocations of reboot/halt (#45966) - fix typo in ifup-wireless - don't muck with /etc/issue each boot +- big IPv6 update () * Fri Jul 6 2001 Trond Eivind Glomsrød - Add new directories required by new network tool diff --git a/ipv6-6to4.howto b/ipv6-6to4.howto new file mode 100644 index 00000000..40af57d4 --- /dev/null +++ b/ipv6-6to4.howto @@ -0,0 +1,120 @@ +v1.1 18th Apr 2001, Pekka Savola +v1.2 23th May 2001, Pekka Savola + +HOW TO SET UP IPV6 WITH 6TO4 +---------------------------- + +6TO4 IN SHORT +------------- + +6to4 is a method of creating automatic IPv6 tunnels. You can connect to +IPv6 Internet very easily without a need for a manually configured tunnel. + +For every globally unique IPv4 address, there exists a mapping for a +subnettable /48 network (2^16 for subnetting, 2^64 bits for hosts). + +Return route can sometimes be non-optimal, leading to higher round-trip times. + +See below for references and more information. + +ASSUMPTIONS +----------- + +1. You're running Red Hat Linux 7.1 or later. + + This is required for correct IPv6 by default settings, and IPv6 being + enabled as a kernel module by default. + +2. Your initscripts >= 5.83.2, for 6to4 support. + +3. You have a static, globally unique IPv4 address. This is not an absolute + requirement, but the only scenario discussed here. + +4. Protocol 41 (IPv6) is not being filtered in any firewall. + +5. 'iproute' package is installed. This is used by default for a lot + more powerful tunneling capabilities. + +INFORMATION NEEDED +------------------ + +You need to know: + +1. The IPv4 address of a 6to4 relay router + +See: http://www.kfu.com/~nsayer/6to4/ for public ones. + +Here, 194.95.108.191 (6to4.ipv6.fh-regensburg.de) is used. + +SETTING UP THE 6TO4 CONFIGURATION +--------------------------------- + +Now, set up the configuration as follows: + +1. Add 'NETWORKING_IPV6=yes' to /etc/sysconfig/network: + + echo "NETWORKING_IPV6=yes" >> /etc/sysconfig/network + +2. Add static routes to IPv6 Internet (this includes 6bone): + + echo "sit0 2000::/3" >> /etc/sysconfig/static-routes-ipv6 + +NOTE: sit0 is used for 6to4 routing. + +3. Edit your outbound (Internet) interface configuration. This can be +e.g. ippp0, eth0, or the like. Here, eth0 is used. + +/etc/sysconfig/network-scripts/ifcfg-eth0: +--- +DEVICE=eth0 +BOOTPROTO=static +ONBOOT=yes +IPADDR=xx.yy.zz.ww +NETMASK=aa.bb.cc.dd [IPv4 settings up to this point] + +IPV6INIT=yes +IPV6TO4INIT=yes +IPV6TO4_RELAY=194.95.108.191 +--- + +USING 6TO4 +---------- + +6to4 automatic tunneling is brought up when the interface is brought up. + +You will see your 6to4 address prefix in device sit0 when done: + + inet6 addr: 2002:c15e:a001::1/48 Scope:Global + +Note that 'c15e:a001' is the hexadecimal representation of dotted-quad IPv4 +address (IPADDR= above), here '193.94.160.1'. + +NOTE: iproute tools give more reliable data, try e.g. '/sbin/ip addr ls'. + +SUBNETTING +---------- + +If you want to provide IPv6 for your LAN using your Linux system as a +router, this can be done rather easily with 6to4. + +You will need to enable IPv6 forwarding (IPV6FORWARDING=yes in +/etc/sysconfig/network) and install a router advertisement daemon. One such, +'radvd' is available in Powertools. + +You must configure the prefix your IPv4 maps to (see sit0 above) in +/etc/radvd.conf or use certain automatic hooks. This is not covered here +in detail; see radvd.conf(5) and /etc/sysconfig/network-scripts/ifup-ipv6 +for details. + +MORE INFORMATION +---------------- + +http://www.bieringer.de/linux/IPv6/IPv6-HOWTO/IPv6-HOWTO.html is a good +source of IPv6 related Linux-information. + +ftp://ftp.isi.edu/in-notes/rfc3056.txt ("Connection of IPv6 Domains via IPv4 +Clouds") is the RFC about 6to4. + +ftp://ftp.itojun.org/pub/paper/draft-itojun-ipv6-transition-abuse-01.txt +("Possible abuse against IPv6 transition technologies") explains some +security considerations in 6to4. diff --git a/ipv6-tunnel.howto b/ipv6-tunnel.howto index 0b79855b..0f5bb7a3 100644 --- a/ipv6-tunnel.howto +++ b/ipv6-tunnel.howto @@ -1,5 +1,6 @@ -4th Mar 2001, Pekka Savola - +v1.0 4th Mar 2001, Pekka Savola +v1.1 18th Apr 2001, Pekka Savola +v1.2 23th May 2001, Pekka Savola HOW TO SET UP AN IPV6 TUNNEL ---------------------------- @@ -17,6 +18,8 @@ ASSUMPTIONS 3. Protocol 41 (IPv6) is not being filtered in any firewall. +4. 'iproute' package is installed. This is used by default for a lot + more powerful tunneling capabilities. INFORMATION NEEDED ------------------ @@ -57,9 +60,8 @@ Now, set up the configuration as follows: echo "NETWORKING_IPV6=yes" >> /etc/sysconfig/network -2. Add static routes to IPv6 Internet: +2. Add static routes to IPv6 Internet (this includes 6bone): - echo "sit1 3ffe::/16" >> /etc/sysconfig/static-routes-ipv6 echo "sit1 2000::/3" >> /etc/sysconfig/static-routes-ipv6 3. Create /etc/sysconfig/network-scripts/ifcfg-sit1, with the following: @@ -70,13 +72,14 @@ BOOTPROTO=none ONBOOT=yes IPV6INIT=yes IPV6TUNNELIPV4=206.123.31.102 -IPV6ADDR=3ffe:b00:c18:1fff:0:0:0:7f5/0 +IPV6ADDR=3ffe:b00:c18:1fff:0:0:0:7f5/128 --- NOTE: You must use _sit1_. sit0 should not be used. -NOTE: You must use prefix /0, else you may not be able to ping your P-t-P -peer without tweaking. +NOTE: Some tunnel endpoints might require a different kind of prefix length; +for example, Cisco's usually favour /126. Using /0 creates a default route +through that interface. NOTE: If you're not directly connected to the Internet, you may want to use ONBOOT=no instead. @@ -89,9 +92,11 @@ Tunnel can be brought up and down with: ifup sit1 ifdown sit1 -NOTE: Even though sit1 is used, 'ifconfig' sees the tunnel as sit0. This -is due to an "interesting" implementation of tunneling -- else multiple -tunnels couldn't be used extensibly. +NOTE: In initscripts <= 5.83 (ie. IPV6_TUNNELMODE=NBMA), even though sit1 is used, +'ifconfig' sees the tunnel as sit0. This is due to an "interesting" implementation +of tunneling -- else multiple tunnels couldn't be used extensibly. + +NOTE: iproute tools give more reliable data, try e.g. '/sbin/ip addr ls'. MORE INFORMATION ---------------- diff --git a/ppp/ip-down.ipv6to4 b/ppp/ip-down.ipv6to4 new file mode 100644 index 00000000..2f481708 --- /dev/null +++ b/ppp/ip-down.ipv6to4 @@ -0,0 +1,105 @@ +#!/bin/sh +# +# ip-down.ipv6to4 +# +# +# Taken from: +# (P) & (C) 2000-2001 by Peter Bieringer +# +# Version 2001-05-07 +# +# Calling parameters: +# $1: interface name +# +# Called by (mostly) /etc/ppp/ip-down.local +# like: /etc/ppp/ip-down.ipv6to4 $1 >>/var/log/ppp-ipv6to4.log 2>&1 +# +# Uses following information from /etc/sysconfig/network: +# NETWORKING_IPV6=yes|no: controls IPv6 initialization (global setting) +# +# Uses following information from /etc/sysconfig/network-scripts/ifcfg-$1: +# IPV6TO4INIT=yes|no: controls configuration +# IPV6TO4_RELAY=IPv4addr: remote IPv6to4 relay address +# IPV6TO4_ROUTING="eth0-:f101::0/64 eth1-:f102::0/64": information to setup local subnetting +# IPV6TO4_CONTROL_RADVD=yes|no: controls radvd triggering +# IPV6TO4_RADVD_PIDFILE=file: PID file of radvd for sending signals, default is "/var/run/radvd/radvd.pid" +# + + +if [ -z "$1" ]; then + echo $"Arg 1 is empty but should contain interface name - skip IPv6to4 initialization" >/dev/stderr + exit 1 +fi + +# Get global network configuration +. /etc/sysconfig/network + +# Source IPv4 helper functions +cd /etc/sysconfig/network-scripts +. network-functions + +CONFIG=$1 +[ -f "$CONFIG" ] || CONFIG=ifcfg-$CONFIG +source_config + +# Test if IPv6 is globally enabled +if [ ! "${NETWORKING_IPV6}" = "yes" ]; then + # Global IPv6 switch not enabled, end now + exit 0 +fi + +if [ ! -f /etc/sysconfig/network-scripts/network-functions-ipv6 ]; then + exit 1 +fi + +. /etc/sysconfig/network-scripts/network-functions-ipv6 + +# Run basic IPv6 test, if not ok, skip IPv6 initialization +test_ipv6 testonly || exit 0 + + +# Shutdown of 6to4, if configured +valid6to4config="yes" +if [ -z "$IPV6TO4_RELAY" ]; then + valid6to4config="no" +fi +if [ "$valid6to4config" = "yes" ]; then + # Beep + if [ -x /usr/bin/beep ]; then /usr/bin/beep -f 2666; else echo -en "\a" >/dev/console; fi + + if [ "$IPV6TO4_CONTROL_RADVD" = "yes" ]; then + # stop RADVD from distributing no longer usable 6to4 prefixes + if [ -z "$IPV6TO4_RADVD_PIDFILE" ]; then + # Take default + IPV6TO4_RADVD_PIDFILE="/var/run/radvd/radvd.pid" + fi + # Send SIGHUP to radvd + if [ -f "$IPV6TO4_RADVD_PIDFILE" ]; then + pid="`cat $IPV6TO4_RADVD_PIDFILE`" + if [ ! -z "$pid" ]; then + # still waiting for feature enabling: stopping distribution of prefixes in RADVD.... + # kill -SOMETHING $pid + false + else + false + fi + fi + fi + + # Delete all static IPv6to4 routes to relay + ifdown_ipv6_route_all sit0 ::$IPV6TO4_RELAY + + if [ ! -z "$IPV6TO4_ROUTING" ]; then + # Delete routes to local networks + for devsuf in $IPV6TO4_ROUTING; do + dev="`echo $devsuf | awk -F- '{ print $1 }'`" + ifdown_ipv6_route_all $dev :: + done + fi + + # Delete all configured 6to4 address + ifdown_ipv6to4_all sit0 + + # Beep + if [ -x /usr/bin/beep ]; then /usr/bin/beep -f 2000; else echo -en "\a" >/dev/console; fi +fi diff --git a/ppp/ip-up.ipv6to4 b/ppp/ip-up.ipv6to4 new file mode 100644 index 00000000..6767703c --- /dev/null +++ b/ppp/ip-up.ipv6to4 @@ -0,0 +1,160 @@ +#!/bin/bash +# +# ip-up.ipv6to4 +# +# +# Taken from: +# (P) & (C) 2000-2001 by Peter Bieringer +# +# Version 2001-05-07 +# +# Calling parameters: +# $1: interface name +# +# Called by (mostly) /etc/ppp/ip-up.local +# like: /etc/ppp/ip-up.ipv6to4 $1 >>/var/log/ppp-ipv6to4.log 2>&1 +# +# Uses following information from /etc/sysconfig/network: +# NETWORKING_IPV6=yes|no: controls IPv6 initialization (global setting) +# +# Uses following information from /etc/sysconfig/network-scripts/ifcfg-$1: +# IPV6TO4INIT=yes|no: controls configuration +# IPV6TO4_IPV4ADDR=IPv4addr: special local address for 6to4 tunneling (only needed behind a NAT gateway) +# IPV6TO4_RELAY=IPv4addr: remote IPv6to4 relay address +# IPV6TO4_ROUTING="eth0-:f101::0/64 eth1-:f102::0/64": information to setup local subnetting +# IPV6TO4_CONTROL_RADVD=yes|no: controls radvd triggering +# IPV6TO4_RADVD_PIDFILE=file: PID file of radvd for sending signals, default is "/var/run/radvd/radvd.pid" +# +# Requirements +# radvd-0.6.2p3 or newer supporting option "Base6to4Interface" +# + + +if [ -z "$1" ]; then + echo $"Option 1 is empty but should contain interface name - skip IPv6to4 initialization" >/dev/stderr + exit 1 +fi + +# Get global network configuration +. /etc/sysconfig/network + +# Source IPv4 helper functions +cd /etc/sysconfig/network-scripts +. network-functions + +CONFIG=$1 +[ -f "$CONFIG" ] || CONFIG=ifcfg-$CONFIG +source_config + +# Test if IPv6 is globally enabled +if [ ! "${NETWORKING_IPV6}" = "yes" ]; then + # Global IPv6 switch not enabled, end now + exit 0 +fi + +if [ ! -f /etc/sysconfig/network-scripts/network-functions-ipv6 ]; then + # IPv6 setup isn't well + exit 1 +fi + +. /etc/sysconfig/network-scripts/network-functions-ipv6 + +# Run basic IPv6 test (and make sure the ipv6 module will be loaded), if not ok, skip IPv6 initialization +test_ipv6 || exit 1 + + +# Setup of 6to4, if configured +valid6to4config="yes" +if [ "$IPV6TO4INIT" = "yes" ]; then + if [ ! -z "$IPV6TO4_IPV4ADDR" ]; then + # Take special configured from config file (precedence 1) + ipv4addr="$IPV6TO4_IPV4ADDR" + else + # Get IPv4 address from interface first (has precedence 2) + ipv4addr="`LC_ALL=C ifconfig $DEVICE |grep "inet addr:" | tr : " " | awk '{ print $3 }'`" + if [ -z "$ipv4addr" ]; then + # Take configured from config file (precedence 3) + ipv4addr="$IPADDR" + fi + fi + if [ ! -z "$ipv4addr" ]; then + # Test for non-global IPv4 address + if ! testipv4_globalusable $ipv4addr; then + echo $"Given IPv4 address $ipv4addr is not a globally usable one, 6to4 configuration is not valid!" + valid6to4config="no" + fi + if [ -z "$IPV6TO4_RELAY" ]; then + echo $"IPv6to4 configuration needs an IPv6to4 relay address, 6to4 configuration is not valid!" + valid6to4config="no" + fi + else + echo $"IPv6to4 configuration needs an IPv4 address on related interface or extra specified, 6to4 configuration is not valid!" + valid6to4config="no" + fi + if [ "$valid6to4config" = "yes" ]; then + # Beep + if [ -x /usr/bin/beep ]; then /usr/bin/beep -f 2000; else echo -en "\a" >/dev/console; fi + + # Cleanup all old data (needed, if "ip-down.ipv6to4" wasn't executed) + + # Delete all static IPv6to4 routes to relay + ifdown_ipv6_route_all sit0 ::$IPV6TO4_RELAY + + # Delete routes to local networks + for devsuf in $IPV6TO4_ROUTING; do + dev="`echo $devsuf | awk -F- '{ print $1 }'`" + ifdown_ipv6_route_all $dev :: + done + + # Delete all configured 6to4 address + ifdown_ipv6to4_all sit0 + + # Setup new data + ifup_ipv6to4 $DEVICE $ipv4addr || exit 1 + + if [ -f /etc/sysconfig/static-routes-ipv6 ]; then + grep "^sit0" /etc/sysconfig/static-routes-ipv6 | while read device args; do + if [ "$device" = "sit0" ]; then + ifup_ipv6_route $args ::$IPV6TO4_RELAY sit0 + fi + done + fi + + if [ "$IPV6TO4_CONTROL_RADVD" = "yes" ]; then + if [ -z "$IPV6TO4_RADVD_PIDFILE" ]; then + # Take default + IPV6TO4_RADVD_PIDFILE="/var/run/radvd/radvd.pid" + fi + + # Send SIGHUP to radvd + if [ -f "$IPV6TO4_RADVD_PIDFILE" ]; then + pid="`cat $IPV6TO4_RADVD_PIDFILE`" + if [ ! -z "$pid" ]; then + echo $"Trigger RADVD for IPv6to4 prefix recalculation" + kill -HUP $pid + else + false + fi + fi + if [ ! -z "$IPV6TO4_ROUTING" ]; then + # Generate 6to4 address + ipv6to4prefix="`create6to4prefix $ipv4addr`" + if [ ! -z "$ipv6to4prefix" ]; then + # Add route to local networks + for devsuf in $IPV6TO4_ROUTING; do + dev="`echo $devsuf | awk -F- '{ print $1 }'`" + suf="`echo $devsuf | awk -F- '{ print $2 }'`" + ifup_ipv6_route ${ipv6to4prefix}$suf :: $dev + done + else + echo $"Error occured while calculating the IPv6to4 prefix" + fi + else + echo $"RADVD control enabled, but config is not complete!" + fi + fi + + # Beep + if [ -x /usr/bin/beep ]; then /usr/bin/beep -f 2666; else echo -en "\a" >/dev/console; fi + fi +fi diff --git a/rc.d/init.d/network b/rc.d/init.d/network index 60913df7..b1983871 100755 --- a/rc.d/init.d/network +++ b/rc.d/init.d/network @@ -51,6 +51,12 @@ interfaces=`ls ifcfg* | LANG=C egrep -v '(ifcfg-lo|:|rpmsave|rpmorig|rpmnew)' | # See how we were called. case "$1" in start) + # IPv6 hook (pre IPv4 start) + if [ "$NETWORKING_IPV6" = "yes" ]; then + if [ -x /etc/sysconfig/network-scripts/init.ipv6-global ]; then + /etc/sysconfig/network-scripts/init.ipv6-global start pre + fi + fi action $"Setting network parameters: " sysctl -e -p /etc/sysctl.conf @@ -135,6 +141,13 @@ case "$1" in done fi + # IPv6 hook (post IPv4 start) + if [ "$NETWORKING_IPV6" = "yes" ]; then + if [ -x /etc/sysconfig/network-scripts/init.ipv6-global ]; then + /etc/sysconfig/network-scripts/init.ipv6-global start post + fi + fi + touch /var/lock/subsys/network ;; stop) @@ -150,6 +163,13 @@ case "$1" in fi fi + # IPv6 hook (pre IPv4 stop) + if [ "$NETWORKING_IPV6" = "yes" ]; then + if [ -x /etc/sysconfig/network-scripts/init.ipv6-global ]; then + /etc/sysconfig/network-scripts/init.ipv6-global stop pre + fi + fi + for i in $interfaces ; do if LC_ALL= LANG= ifconfig $i 2>/dev/null | grep -q " UP " >/dev/null 2>&1 ; then action $"Shutting down interface $i: " ./ifdown $i boot @@ -175,6 +195,13 @@ case "$1" in fi fi fi + + # IPv6 hook (post IPv4 stop) + if [ "$NETWORKING_IPV6" = "yes" ]; then + if [ -x /etc/sysconfig/network-scripts/init.ipv6-global ]; then + /etc/sysconfig/network-scripts/init.ipv6-global stop post + fi + fi rm -f /var/lock/subsys/network ;; diff --git a/sysconfig.txt b/sysconfig.txt index 576400a4..fc49749b 100644 --- a/sysconfig.txt +++ b/sysconfig.txt @@ -115,8 +115,32 @@ Files in /etc/sysconfig IPXAUTOFRAME=on|off (again, not yes|no) IPXINTERNALNETNUM= IPXINTERNALNODENUM= + NETWORKING_IPV6=yes|no Enable or disable global IPv6 initialization + IPV6FORWARDING=yes|no + Enable or disable global forwarding of incoming IPv6 packes + on all interfaces. + Note: Actual packet forwarding cannot be controlled per-device. + IPV6INIT=yes|no + Enable or disable IPv6 configuration for all interfaces. + Use with caution! + + IPV6_AUTOCONF=yes|no + Sets the default for device-based autoconfiguration. + Default: yes if IPV6FORWARDING=no, no if IPV6FORWARDING=yes + IPV6_ROUTER=yes|no + Sets the default for device-based Host/Router behaviour. + Default: yes if IPV6FORWARDING=yes, no if IPV6FORWARDING=no + IPV6_AUTOTUNNEL=yes|no + Controls automatic IPv6 tunneling. + + IPV6_TUNNELMODE=IP|NBMA [OPTIONAL: IP by default] + Mode of tunnel setup + IP: separate tunnel device mode (now recommeded) + NBMA: NBMA-styled tunnel mode (now mostly obsolete) + + All IPv6 options can be overridden in interface-specific configuration. All the IPX stuff is optional, and should default to off. @@ -347,6 +371,11 @@ Files in /etc/sysconfig/network-scripts/ be brought up on boot (ONBOOT=no, see below) can be ignored at that time. +/etc/sysconfig/network-scripts/init.ipv6-global: + Not really a public file. Contains different basic settings that + are set from /etc/rc.d/init.d/network at different stages of + network initialization. + /etc/sysconfig/network-scripts/network-functions: Not really a public file. Contains functions which the scripts use @@ -407,10 +436,10 @@ Files in /etc/sysconfig/network-scripts/ IPv6-only items for real interfaces: IPV6INIT=yes|no - enable or disable IPv6 configuration for this interface + Enable or disable IPv6 configuration for this interface IPV6FORWARDING=yes|no - enable or disable forwarding of incoming IPv6 packes on this - interface (perhaps moved to sysctl in the future) + Enable or disable global forwarding of incoming IPv6 packets + Note! Obsolete in interface specification. IPV6ADDR=/ specify primary static IPv6 address here Example: @@ -420,16 +449,44 @@ Files in /etc/sysconfig/network-scripts/ Example: IPV6ADDR_SECONDARIES="3ffe:400:100:f101::10/64 3ffe:400:100:f101::11/64" + Special configuration options for multi-homed hosts etc. + IPV6_ROUTER=yes|no: controls IPv6 autoconfiguration + IPV6_AUTOCONF=yes|no: controls IPv6 autoconfiguration + defaults: + global IPV6FORWARDING=yes: IPV6_AUTOCONF=no, IPV6_ROUTER=yes + global IPV6FORWARDING=no: IPV6_AUTOCONF=yes + + Optional settings for a 6to4 tunnel + IPV6TO4INIT=yes|no + Enable or disable 6to4 tunneling setup + IPV6TO4_RELAY= + IPv4 address of the remote 6to4 relay + IPV6TO4_IPV4ADDR= [OPTIONAL] + overwrite local IPv4 address which is accessable from the Internet + (optional, in case of NAT or other special scenarios) + IPV6TO4_ROUTING= [OPTIONAL] + a list of routing tokens to setup proper IPv6 routes on the LAN + Example: + IPV6TO4_ROUTING="eth0-:f101::0/64 eth1-:f102::0/64" + Will create one route per eth0 and eth1, taking given SLA + IPV6TO4_CONTROL_RADVD=yes|no [OPTIONAL] + Enable signalling radvd that the 6to4 prefix has been changed + IPV6TO4_RADVD_PIDFILE= [OPTIONAL] + location of PID file to get PID for sending signal + default is "/var/run/radvd/radvd.pid" + Example: + IPV6TO4_RADVD_PIDFILE="/some/other/location/radvd.pid" + IPv6-only items for automatic tunnel interface: Virtual interface name: sit0 IPV6INIT=yes|no - enable or disable IPv6 configuration for this interface - (Perhaps this configuration will be moved to /etc/rc.d/init.d/network in the future) - + Enable or disable IPv6 configuration for this interface + Obsolete now, see IPV6_AUTOTUNNEL in /etc/sysconfig/network + IPv6-only items for static unnumbered tunnel interface: Virtual interface name: sit1.. IPV6INIT=yes|no - enable or disable IPv6 configuration for this interface + Enable or disable IPv6 configuration for this interface IPV6TUNNELIPV4= specify IPv4 address of a foreign IPv6-in-IPv4 tunnel endpoint Example: diff --git a/sysconfig/network-scripts/ifdown b/sysconfig/network-scripts/ifdown index c63864bb..1cd03d7c 100755 --- a/sysconfig/network-scripts/ifdown +++ b/sysconfig/network-scripts/ifdown @@ -48,7 +48,7 @@ fi check_device_down ${DEVICE} && exit 0 if [ "${NETWORKING_IPV6}" = "yes" ]; then - /etc/sysconfig/network-scripts/ifdown-ipv6 $DEVICE + /etc/sysconfig/network-scripts/ifdown-ipv6 ${CONFIG} fi retcode=0 diff --git a/sysconfig/network-scripts/ifdown-ipv6 b/sysconfig/network-scripts/ifdown-ipv6 index 45c7f24d..d111d1cb 100755 --- a/sysconfig/network-scripts/ifdown-ipv6 +++ b/sysconfig/network-scripts/ifdown-ipv6 @@ -6,9 +6,27 @@ # Taken from: # (P) & (C) 2000-2001 by Peter Bieringer # -# Version 2001-02-08 +# RHL integration assistance by Pekka Savola +# +# Version 2001-05-22d +# +# Uses following information from /etc/sysconfig/network: +# NETWORKING_IPV6=yes|no: controls IPv6 initialization (global setting) +# +# Uses following information from /etc/sysconfig/network-scripts/ifcfg-$1: +# IPV6INIT=yes|no: controls IPv6 configuration for this interface +# +# Optional for 6to4 tunneling: +# IPV6TO4_RELAY=: IPv4 address of the remote 6to4 relay +# IPV6TO4_ROUTING="eth0-:f101::0/64 eth1-:f102::0/64": information to setup local subnetting +# IPV6TO4_CONTROL_RADVD=yes|no: controls radvd triggering [optional] +# IPV6TO4_RADVD_PIDFILE=file: PID file of radvd for sending signals, default is "/var/run/radvd/radvd.pid" [optional] +# +# Requirements for 6to4 if using radvd: +# radvd-0.6.2p3 or newer supporting option "Base6to4Interface" # + . /etc/sysconfig/network cd /etc/sysconfig/network-scripts @@ -18,42 +36,68 @@ CONFIG=$1 [ -f "$CONFIG" ] || CONFIG=ifcfg-$CONFIG source_config -# Test if IPv6 configuration is enabled -if [ ! "$IPV6INIT" = "yes" ]; then - # not enabled, stop here - exit 0 +# Test if IPv6 is globally enabled +if [ ! "${NETWORKING_IPV6}" = "yes" ]; then + # Global IPv6 switch not enabled, end now + exit 0 +fi + +if [ ! -f /etc/sysconfig/network-scripts/network-functions-ipv6 ]; then + # IPv6 setup isn't well + exit 1 fi - -# Test if IPv6 is up -if [ "${NETWORKING_IPV6}" = "yes" ]; then - . /etc/sysconfig/network-scripts/network-functions-ipv6 +# Source IPv6 helper functions +. /etc/sysconfig/network-scripts/network-functions-ipv6 + +# IPv6 test, no module loaded, exit if system is not IPv6-ready +test_ipv6 testonly || exit 0 - # Delete additional static IPv6 routes on specified interface - if [ -f /etc/sysconfig/static-routes-ipv6 ]; then - grep "^$DEVICE" /etc/sysconfig/static-routes-ipv6 | while read device args; do - if [ "$device" = "$DEVICE" ]; then - ifdown_ipv6_route $args $DEVICE + +# Switch some sysctls to secure mode +sysctl -w net.ipv6.conf.$DEVICE.forwarding=0 >/dev/null +sysctl -w net.ipv6.conf.$DEVICE.accept_ra=0 >/dev/null +sysctl -w net.ipv6.conf.$DEVICE.accept_redirects=0 >/dev/null + +# Shutdown of 6to4, if configured +valid6to4config="yes" +if [ -z "$IPV6TO4_RELAY" ]; then + valid6to4config="no" +fi +if [ "$valid6to4config" = "yes" ]; then + if [ "$IPV6TO4_CONTROL_RADVD" = "yes" ]; then + # stop RADVD from distributing no longer usable 6to4 prefixes + if [ -z "$IPV6TO4_RADVD_PIDFILE" ]; then + # Take default + IPV6TO4_RADVD_PIDFILE="/var/run/radvd/radvd.pid" + fi + # Send SIGHUP to radvd + if [ -f "$IPV6TO4_RADVD_PIDFILE" ]; then + pid="`cat $IPV6TO4_RADVD_PIDFILE`" + if [ ! -z "$pid" ]; then + # still waiting for feature enabling: stopping distribution of prefixes in RADVD.... + # kill -SOMETHING $pid + false + else + false fi - done + fi fi - # Switch off forwarding per device (packets received on this - # interface aren't forwarded - forwarding_ipv6 no $DEVICE - - # Delete additional IPv6 addresses from list - if [ ! -z "$IPV6ADDR_SECONDARIES" ]; then - for ipv6addr in $IPV6ADDR_SECONDARIES; do - ifdown_ipv6_real $DEVICE $ipv6addr + if [ ! -z "$IPV6TO4_ROUTING" ]; then + # Delete routes to local networks + for devsuf in $IPV6TO4_ROUTING; do + dev="`echo $devsuf | awk -F- '{ print $1 }'`" + ifdown_ipv6_route_all $dev :: done fi - - # Shutdown basic configured IPv6 address on specified interface - if ! [ -z "$IPV6ADDR" ]; then - ifdown_ipv6_real $DEVICE $IPV6ADDR - fi - # Cleanup all IPv6 configuration on specified interface (prevents from kernel crashing) - ifdown_ipv6_real_all $DEVICE -fi + # Delete all static IPv6to4 routes + ifdown_ipv6_route_all sit0 ::$IPV6TO4_RELAY + + # Delete all configured 6to4 address + ifdown_ipv6to4_all sit0 +fi + +# Delete all current configured IPv6 addresses on this interface +ifdown_ipv6_real_all $DEVICE diff --git a/sysconfig/network-scripts/ifdown-sit b/sysconfig/network-scripts/ifdown-sit index a70d5169..a2a70c16 100755 --- a/sysconfig/network-scripts/ifdown-sit +++ b/sysconfig/network-scripts/ifdown-sit @@ -6,13 +6,24 @@ # Taken from: # (P) & (C) 2000-2001 by Peter Bieringer # -# Version 2001-02-08 +# RHL integration assistance by Pekka Savola +# +# Version 2001-05-22d +# +# Uses following information from /etc/sysconfig/network: +# NETWORKING_IPV6=yes|no: controls IPv6 initialization (global setting) +# +# Uses following information from "/etc/sysconfig/network-scripts/ifcfg-$1": +# For static tunnels +# IPV6TUNNELIPV4="" +# IPV6ADDR=/ [OPTIONAL: numbered tunnels] # -# Filter tags (for stripping, empty lines following if all is stripped) +# Get global network configuration . /etc/sysconfig/network +# Source IPv4 helper functions cd /etc/sysconfig/network-scripts . network-functions @@ -20,33 +31,43 @@ CONFIG=$1 [ -f "$CONFIG" ] || CONFIG=ifcfg-$CONFIG source_config -# Test if IPv6 configuration is enabled for this interface -if [ ! "$IPV6INIT" = "yes" ]; then - # not enabled, stop here - exit 0 -fi - # Test if IPv6 is up -if [ "${NETWORKING_IPV6}" = "yes" ]; then - - . /etc/sysconfig/network-scripts/network-functions-ipv6 - - # Delete IPv6-in-IPv4 tunnel(s) - if [ "$DEVICE" = "sit0" ]; then - ifdown_ipv6_autotunnel - elif [ ! -z "$IPV6TUNNELIPV4" ]; then - # Delete static IPv6 tunnel routes on specified virtual interface - if [ -f /etc/sysconfig/static-routes-ipv6 ]; then - grep "^$DEVICE" /etc/sysconfig/static-routes-ipv6 | while read device ipv6route args; do - if [ "$device" = "$DEVICE" ]; then - ifdown_ipv6_tunnel $DEVICE $IPV6TUNNELIPV4 $ipv6route - fi - done +if [ ! "${NETWORKING_IPV6}" = "yes" ]; then + # Global IPv6 switch not enabled, end now + exit 0 +fi + +if [ ! -f /etc/sysconfig/network-scripts/network-functions-ipv6 ]; then + # IPv6 setup isn't well + exit 1 +fi + +# Source IPv6 helper functions +. /etc/sysconfig/network-scripts/network-functions-ipv6 + +# IPv6 test, no module loaded, exit if system is not IPv6-ready +test_ipv6 testonly || exit 0 + +# Delete IPv6-in-IPv4 tunnel(s) +if [ "$DEVICE" = "sit0" ]; then + ifdown_ipv6_autotunnel +elif [ ! -z "$IPV6TUNNELIPV4" ]; then + if [ "$IPV6_TUNNELMODE" = "NBMA" ]; then + if [ ! -z "$IPV6ADDR" ]; then + # Numbered tunnel + ifdown_ipv6_real sit0 $IPV6ADDR fi - if [ ! -z "$IPV6ADDR" ]; then - # Numbered tunnel - ifdown_ipv6_real sit0 $IPV6ADDR + # Cleanup all IPv6 tunnel configuration on specified interface and shut down sit0, if no longer used + ifdown_ipv6_tunnel_all $DEVICE $IPV6TUNNELIPV4 + + elif [ -z "$IPV6_TUNNELMODE" -o "$IPV6_TUNNELMODE" = "IP" ]; then + # Delete all IPv6 routes and addresses + ifdown_ipv6_real_all $DEVICE + + # Shut down tunnel device + ifdown_ipv6_tunneldev $DEVICE + else + echo $"Tunnel creation mode '$IPV6_TUNNELMODE' not supported - skip!" fi - fi -fi +fi diff --git a/sysconfig/network-scripts/ifup b/sysconfig/network-scripts/ifup index 6a418d40..214f42ea 100755 --- a/sysconfig/network-scripts/ifup +++ b/sysconfig/network-scripts/ifup @@ -167,7 +167,7 @@ if [ -n "${DYNCONFIG}" ]; then if [ -x /sbin/dhcpcd ] && /sbin/dhcpcd ${DHCPCDARGS} ${DEVICE} ; then echo $" done." - elif [ -x /sbin/pump ] && /sbin/pump ${PUMPARGS} -i ${DEVICE} ; then + elif [ -x /sbin/pump ] && /sbin/pump ${PUMPARGS} -i ${DEVICE}; then echo $" done." else echo $" failed." @@ -180,6 +180,9 @@ else if [ -z "${IPADDR}" ]; then # enable device without IP, useful for e.g. PPPoE ip link set ${DEVICE} up + if [ "${NETWORKING_IPV6}" = "yes" ]; then + /etc/sysconfig/network-scripts/ifup-ipv6 ${CONFIG} + fi exec /etc/sysconfig/network-scripts/ifup-post ${CONFIG} ${2} fi @@ -246,7 +249,7 @@ fi # IPv6 initialisation? if [ "${NETWORKING_IPV6}" = "yes" ]; then - /etc/sysconfig/network-scripts/ifup-ipv6 $DEVICE + /etc/sysconfig/network-scripts/ifup-ipv6 ${CONFIG} fi exec /etc/sysconfig/network-scripts/ifup-post ${CONFIG} ${2} diff --git a/sysconfig/network-scripts/ifup-ipv6 b/sysconfig/network-scripts/ifup-ipv6 index 4ee50e1e..b8a5c71c 100755 --- a/sysconfig/network-scripts/ifup-ipv6 +++ b/sysconfig/network-scripts/ifup-ipv6 @@ -6,13 +6,40 @@ # Taken from: # (P) & (C) 2000-2001 by Peter Bieringer # -# Version 2001-03-03 +# RHL integration assistance by Pekka Savola +# +# Version 2001-05-22d +# +# Uses following information from "/etc/sysconfig/network": +# NETWORKING_IPV6=yes|no: controls IPv6 initialization (global setting) +# +# Uses following information from "/etc/sysconfig/network-scripts/ifcfg-$1": +# IPV6INIT=yes|no: controls IPv6 configuration for this interface +# IPV6ADDR=/: specify primary static IPv6 address here +# IPV6ADDR_SECONDARIES="" [optional] +# IPV6_ROUTER=yes|no: controls IPv6 autoconfiguration (no: multi-homed interface without routing) +# IPV6_AUTOCONF=yes|no: controls IPv6 autoconfiguration +# defaults: +# IPV6FORWARDING=yes: IPV6_AUTOCONF=no, IPV6_ROUTER=yes +# IPV6FORWARDING=no: IPV6_AUTOCONF=yes +# +# Optional for 6to4 tunneling: +# IPV6TO4INIT=yes|no: controls 6to4 tunneling setup +# IPV6TO4_RELAY=: IPv4 address of the remote 6to4 relay +# IPV6TO4_IPV4ADDR=: overwrite local IPv4 address [optional] +# IPV6TO4_ROUTING="eth0-:f101::0/64 eth1-:f102::0/64": information to setup local subnetting +# IPV6TO4_CONTROL_RADVD=yes|no: controls radvd triggering [optional] +# IPV6TO4_RADVD_PIDFILE=file: PID file of radvd for sending signals, default is "/var/run/radvd/radvd.pid" [optional] +# +# Requirements for 6to4 if using radvd: +# radvd-0.6.2p3 or newer supporting option "Base6to4Interface" # -# Filter tags (for stripping, empty lines following if all is stripped) +# Get global network configuration . /etc/sysconfig/network +# Source IPv4 helper functions cd /etc/sysconfig/network-scripts . network-functions @@ -27,43 +54,171 @@ if [ ! "$IPV6INIT" = "yes" ]; then fi # Test if IPv6 is up -if [ "${NETWORKING_IPV6}" = "yes" ]; then +if [ ! "${NETWORKING_IPV6}" = "yes" ]; then + # Global IPv6 switch not enabled, end now + exit 0 +fi + +if [ ! -f /etc/sysconfig/network-scripts/network-functions-ipv6 ]; then + # IPv6 setup isn't well + exit 1 +fi - . /etc/sysconfig/network-scripts/network-functions-ipv6 +# Source IPv6 helper functions +. /etc/sysconfig/network-scripts/network-functions-ipv6 + +# IPv6 test, module loaded, exit if system is not IPv6-ready +test_ipv6 || exit 1 - # Run basic IPv6 test (and make sure the ipv6 module will be loaded) - test_ipv6 || exit 0 - # Setup IPv6 address on specified interface - if ! [ -z "$IPV6ADDR" ]; then - ifup_ipv6_real $DEVICE $IPV6ADDR +# Setup IPv6 address on specified interface +if ! [ -z "$IPV6ADDR" ]; then + ifup_ipv6_real $DEVICE $IPV6ADDR +fi + +# Get current global IPv6 forwarding +ipv6_global_forwarding_current="`sysctl -n net.ipv6.conf.all.forwarding`" + +# Set some proc switches depending on defines +if [ "$IPV6FORWARDING" = "yes" ]; then + # Global forwarding should be enabled + + # Check, if global IPv6 forwarding was already set by global script + if [ $ipv6_global_forwarding_current -ne 1 ]; then + # Forwarding enabled, but not set, display warning + echo $"Global IPv6 forwarding is enabled in configuration, but not currently enabled in kernel" + echo $"Please restart network with '/etc/rc.d/init.d/network restart'" fi - - # Switch forwarding per device like defined - # Packets received on selected interface are forwarded - if ! [ -z "$IPV6FORWARDING" ]; then - if [ "$IPV6FORWARDING" = "yes" ]; then - forwarding_ipv6 yes $DEVICE - # also for all (otherwise, nothing is forwarded) - forwarding_ipv6 yes - else - forwarding_ipv6 no $DEVICE - fi + + ipv6_local_forwarding=1 + ipv6_local_auto=0 + if [ "$IPV6_ROUTER" = "no" ]; then + # Interface should not act as a Router + ipv6_local_forwarding=0 fi - - # Setup additional IPv6 addresses from list - if [ ! -z "$IPV6ADDR_SECONDARIES" ]; then - for ipv6addr in $IPV6ADDR_SECONDARIES; do - ifup_ipv6_real $DEVICE $ipv6addr - done + if [ "$IPV6_AUTOCONF" = "yes" ]; then + # Interface should be autoconfigured + ipv6_local_auto=1 + fi +else + # Global forwarding should be disabled + + # Check, if global IPv6 forwarding was already set by global script + if [ $ipv6_global_forwarding_current -ne 0 ]; then + # Forwarding disabled, but not set, display warning + echo $"Global IPv6 forwarding is disabled in configuration, but not currently disabled in kernel" + echo $"Please restart network with '/etc/rc.d/init.d/network restart'" fi - # Setup additional static IPv6 routes on specified interface - if [ -f /etc/sysconfig/static-routes-ipv6 ]; then - grep "^$DEVICE" /etc/sysconfig/static-routes-ipv6 | while read device args; do - if [ "$device" = "$DEVICE" ]; then - ifup_ipv6_route $args $DEVICE + ipv6_local_forwarding=0 + ipv6_local_auto=1 + if [ "$IPV6_AUTOCONF" = "no" ]; then + # Interface should not be autoconfigured + ipv6_local_auto=0 + fi +fi +sysctl -w net.ipv6.conf.$DEVICE.forwarding=$ipv6_local_forwarding >/dev/null +sysctl -w net.ipv6.conf.$DEVICE.accept_ra=$ipv6_local_auto >/dev/null +sysctl -w net.ipv6.conf.$DEVICE.accept_redirects=$ipv6_local_auto >/dev/null + +# Setup additional IPv6 addresses from list +if [ ! -z "$IPV6ADDR_SECONDARIES" ]; then + for ipv6addr in $IPV6ADDR_SECONDARIES; do + ifup_ipv6_real $DEVICE $ipv6addr + done +fi + +# Setup additional static IPv6 routes on specified interface +if [ -f /etc/sysconfig/static-routes-ipv6 ]; then + grep "^$DEVICE\W" /etc/sysconfig/static-routes-ipv6 | while read device args; do + if [ "$device" = "$DEVICE" ]; then + ifup_ipv6_route $args $DEVICE + fi + done +fi + +# Setup of 6to4, if configured +if [ "$IPV6TO4INIT" = "yes" ]; then + valid6to4config="yes" + if [ ! -z "$IPV6TO4_IPV4ADDR" ]; then + # Take special configured from config file (precedence 1) + ipv4addr="$IPV6TO4_IPV4ADDR" + else + # Get IPv4 address from interface first (has precedence 2) + ipv4addr="`LC_ALL=C ifconfig $DEVICE |grep "inet addr:" | tr : " " | awk '{ print $3 }'`" + if [ -z "$ipv4addr" ]; then + # Take configured from config file (precedence 3) + ipv4addr="$IPADDR" + fi + fi + if [ ! -z "$ipv4addr" ]; then + # Test for non-global IPv4 address + if ! testipv4_globalusable $ipv4addr; then + echo $"Given IPv4 address $ipv4addr is not a globally usable one, 6to4 configuration is not valid!" + valid6to4config="no" + fi + if [ -z "$IPV6TO4_RELAY" ]; then + echo $"IPv6to4 configuration needs an IPv6to4 relay address, 6to4 configuration is not valid!" + valid6to4config="no" + fi + if [ "$valid6to4config" = "yes" ]; then + if ! testipv4_globalusable $IPV6TO4_RELAY; then + echo $"Given IPv4 address of relay is not a globally usable one, 6to4 configuration is not valid!" + valid6to4config="no" fi - done + fi + else + echo $"IPv6to4 configuration needs an IPv4 address on related interface or extra specified, 6to4 configuration is not valid!" + valid6to4config="no" fi -fi + if [ "$valid6to4config" = "yes" ]; then + ifup_ipv6to4 $DEVICE $ipv4addr + if [ -f /etc/sysconfig/static-routes-ipv6 ]; then + grep "^sit0" /etc/sysconfig/static-routes-ipv6 | while read device args; do + if [ "$device" = "sit0" ]; then + ifup_ipv6_route $args ::$IPV6TO4_RELAY sit0 + fi + done + fi + + if [ "$IPV6TO4_CONTROL_RADVD" = "yes" ]; then + # RADVD is in use, so forwarding of IPv6 packets should be enabled + if [ $ipv6_global_forwarding_current -ne 1 ]; then + # Forwarding not set, display warning + echo $"Using 6to4 and RADVD IPv6 forwarding usually should be enabled, but it isn't!" + fi + + if [ -z "$IPV6TO4_RADVD_PIDFILE" ]; then + # Take default + IPV6TO4_RADVD_PIDFILE="/var/run/radvd/radvd.pid" + fi + + # Send SIGHUP to radvd + if [ -f "$IPV6TO4_RADVD_PIDFILE" ]; then + pid="`cat $IPV6TO4_RADVD_PIDFILE`" + if [ ! -z "$pid" ]; then + echo $"Trigger RADVD for IPv6to4 prefix recalculation" + kill -HUP $pid + else + false + fi + fi + if [ ! -z "$IPV6TO4_ROUTING" ]; then + # Generate 6to4 address + ipv6to4prefix="`create6to4prefix $ipv4addr`" + if [ ! -z "$ipv6to4prefix" ]; then + # Add route to local networks + for devsuf in $IPV6TO4_ROUTING; do + dev="`echo $devsuf | awk -F- '{ print $1 }'`" + suf="`echo $devsuf | awk -F- '{ print $2 }'`" + ifup_ipv6_route ${ipv6to4prefix}$suf :: $dev + done + else + echo $"Error occured while calculating the IPv6to4 prefix" + fi + else + echo $"RADVD control enabled, but config is not complete!" + fi + fi + fi +fi diff --git a/sysconfig/network-scripts/ifup-sit b/sysconfig/network-scripts/ifup-sit index ff92aba1..baf78a66 100755 --- a/sysconfig/network-scripts/ifup-sit +++ b/sysconfig/network-scripts/ifup-sit @@ -6,13 +6,27 @@ # Taken from: # (P) & (C) 2000-2001 by Peter Bieringer # -# Version 2001-03-03 +# RHL integration assistance by Pekka Savola +# +# Version 2001-05-22d +# +# Uses following information from "/etc/sysconfig/network": +# NETWORKING_IPV6=yes|no: controls IPv6 initialization (global setting) +# +# Uses following information from "/etc/sysconfig/network-scripts/ifcfg-$1": +# IPV6INIT=yes|no: controls IPv6 configuration for this interface +# IPV6_TUNNELMODE=IP|NBMA: mode of tunnel creation [default: IP] +# +# For static tunnels +# IPV6TUNNELIPV4="" +# IPV6ADDR=/ [OPTIONAL: numbered tunnels] # -# Filter tags (for stripping, empty lines following if all is stripped) +# Get global network configuration . /etc/sysconfig/network +# Source IPv4 helper functions cd /etc/sysconfig/network-scripts . network-functions @@ -22,22 +36,32 @@ source_config # Test if IPv6 configuration is enabled for this interface if [ ! "$IPV6INIT" = "yes" ]; then - # not enabled, stop here exit 0 fi # Test if IPv6 is up -if [ "${NETWORKING_IPV6}" = "yes" ]; then - - . /etc/sysconfig/network-scripts/network-functions-ipv6 +if [ ! "${NETWORKING_IPV6}" = "yes" ]; then + exit 0 +fi + +if [ ! -f /etc/sysconfig/network-scripts/network-functions-ipv6 ]; then + # IPv6 setup isn't well + exit 1 +fi - # Run basic IPv6 test (and make sure the ipv6 module will be loaded) - test_ipv6 || exit 0 +# Source IPv6 helper functions +. /etc/sysconfig/network-scripts/network-functions-ipv6 - # Setup IPv6-in-IPv4 tunnel(s) - if [ "$DEVICE" = "sit0" ]; then - ifup_ipv6_autotunnel - elif [ ! -z "$IPV6TUNNELIPV4" ]; then +# IPv6 test, module loaded, exit if system is not IPv6-ready +test_ipv6 || exit 1 + +# Setup IPv6-in-IPv4 tunnel(s) +if [ "$DEVICE" = "sit0" ]; then + ifup_ipv6_autotunnel || exit 1 + +elif [ ! -z "$IPV6TUNNELIPV4" ]; then + if [ "$IPV6_TUNNELMODE" = "NBMA" ]; then + # NBMA-styled tunneling if [ ! -z "$IPV6ADDR" ]; then # Numbered tunnel ifup_ipv6_real sit0 $IPV6ADDR @@ -51,5 +75,22 @@ if [ "${NETWORKING_IPV6}" = "yes" ]; then fi done fi + elif [ -z "$IPV6_TUNNELMODE" -o "$IPV6_TUNNELMODE" = "IP" ]; then + ifup_ipv6_tunneldev $DEVICE $IPV6TUNNELIPV4 || exit 1 + + if [ ! -z "$IPV6ADDR" ]; then + # Numbered tunnel + ifup_ipv6_real $DEVICE $IPV6ADDR + fi + + if [ -f /etc/sysconfig/static-routes-ipv6 ]; then + grep "^$DEVICE\W" /etc/sysconfig/static-routes-ipv6 | while read device ipv6route args; do + if [ "$device" = "$DEVICE" ]; then + ifup_ipv6_route $ipv6route :: $DEVICE + fi + done + fi + else + echo $"Tunnel creation mode '$IPV6_TUNNELMODE' not supported - skip!" fi -fi +fi diff --git a/sysconfig/network-scripts/init.ipv6-global b/sysconfig/network-scripts/init.ipv6-global new file mode 100755 index 00000000..da46d4ba --- /dev/null +++ b/sysconfig/network-scripts/init.ipv6-global @@ -0,0 +1,188 @@ +#!/bin/sh +# +# init.ipv6-global +# +# +# Taken from: +# (P) & (C) 2001 by Peter Bieringer +# +# RHL integration assistance by Pekka Savola +# +# Version 2001-05-22d +# +# Calling parameters: +# $1: action (currently supported: start|stop|showsysctl) +# $2: position for start|stop (currently supported: pre|post) +# +# Called by hooks from /etc/rc.d/init.d/network +# +# Uses following information from /etc/sysconfig/network: +# NETWORKING_IPV6=yes|no: controls global IPv6 initialization (default: no) +# IPV6FORWARDING=yes|no: controls global IPv6 forwarding (default: no) +# IPV6AUTOCONF=yes|no: controls global automatic IPv6 configuration +# (default: yes if IPV6FORWARDING=no, no if IPV6FORWARDING=yes) +# IPV6_AUTOTUNNEL=yes|no: controls automatic IPv6 tunneling (default: no) +# + + + +# Get global network configuration +. /etc/sysconfig/network + +# Source IPv4 helper functions +cd /etc/sysconfig/network-scripts +. network-functions + +# Get action and hook position +ACTION="$1" +POSITION="$2" + +# Test for IPv6 enabling +if [ ! "${NETWORKING_IPV6}" = "yes" ]; then + exit 0 +fi + +if [ ! -f /etc/sysconfig/network-scripts/network-functions-ipv6 ]; then + exit 1 +fi + +# Source IPv6 helper functions +. /etc/sysconfig/network-scripts/network-functions-ipv6 + +# Initialize IPv6, depending on caller option +case $ACTION in + start) + case $POSITION in + pre) + # IPv6 test, module loaded, exit if system is not IPv6-ready + test_ipv6 || exit 1 + + + if [ "$IPV6FORWARDING" = "yes" ]; then + ipv6_global_forwarding=1 + ipv6_global_auto=0 + else + ipv6_global_forwarding=0 + if [ "$IPV6AUTO" = "no" ]; then + ipv6_global_auto=0 + else + ipv6_global_auto=1 + fi + fi + + # Reset IPv6 sysctl switches for "all", "default" and still existing devices + for i in /proc/sys/net/ipv6/conf/*; do + if [ ! -d $i ]; then + continue + fi + interface="`echo $i | awk -F/ '{ print $NF}'`" + # Host/Router behaviour for the interface + sysctl -w net.ipv6.conf.$interface.forwarding=$ipv6_global_forwarding >/dev/null + + # Autoconfiguration and redirect handling for Hosts + sysctl -w net.ipv6.conf.$interface.accept_ra=$ipv6_global_auto >/dev/null + sysctl -w net.ipv6.conf.$interface.accept_redirects=$ipv6_global_auto >/dev/null + done + + if [ "$IPV6_AUTOTUNNEL" = "yes" ]; then + ifup_ipv6_autotunnel + fi + ;; + + post) + # IPv6 test, module loaded, exit if system is not IPv6-ready + test_ipv6 || exit 1 + + + ## Add some routes which should never appear on the wire + # Unreachable IPv4-only addresses, normally blocked by source address selection + ip route add unreach ::ffff:0.0.0.0/96 + # Unreachable IPv4-mapped addresses + ip route add unreach ::0.0.0.0/96 + # Unreachable 6to4: IPv4 multicast, reserved, limited broadcast + ip route add unreach 2002:e000::/19 + # Unreachable 6to4: IPv4 loopback + ip route add unreach 2002:7f00::/24 + # Unreachable 6to4: IPv4 private (RFC1918) + ip route add unreach 2002:0a00::/24 + ip route add unreach 2002:ac10::/28 + ip route add unreach 2002:c0a8::/32 + # Unreachable 6to4: IPv4 private (DHCP link-local) + ip route add unreach 2002:a9fe::/32 + ;; + + *) + echo "Usage: $0 $1 {pre|post}" + ;; + + esac + ;; + + stop) + case $POSITION in + pre) + # IPv6 test, no module loaded, exit if system is not IPv6-ready + test_ipv6 testonly || exit 0 + + + ;; + + post) + # IPv6 test, no module loaded, exit if system is not IPv6-ready + test_ipv6 testonly || exit 0 + + + for i in /proc/sys/net/ipv6/conf/*; do + if [ ! -d $i ]; then + continue + fi + interface="`echo $i | awk -F/ '{ print $NF}'`" + # Assume Host behaviour + sysctl -w net.ipv6.conf.$interface.forwarding=0 >/dev/null + + # Disable autoconfiguration and redirects + sysctl -w net.ipv6.conf.$interface.accept_ra=0 >/dev/null + sysctl -w net.ipv6.conf.$interface.accept_redirects=0 >/dev/null + done + + # Find still existing tunnel devices and shutdown and delete them + LC_ALL=C ip tunnel | grep "ipv6/ip" | awk -F: '{ print $1 }' | while read device; do + ifdown_ipv6_tunneldev $device + done + + ;; + + *) + echo "Usage: $0 $1 {pre|post}" + ;; + + esac + ;; + + restart|reload) + # do nothing, will be handled by main script + ;; + + showsysctl) + # Run only basic tests, no module is loaded, if not ok, skip IPv6 initialization + test_ipv6 testonly || exit 0 + + # Show sysctl switches + for i in /proc/sys/net/ipv6/conf/default/*; do + if [ ! -f $i ]; then continue; fi + switch="`echo $i | awk -F/ '{ print $NF}'`" + for j in /proc/sys/net/ipv6/conf/*; do + if [ ! -d $j ]; then continue; fi + interface="`echo $j | awk -F/ '{ print $NF}'`" + sysctl net.ipv6.conf.$interface.$switch + done + echo + done + ;; + + *) + echo "Usage: $0 {start|stop|showsysctl}" + exit 1 + ;; + +esac diff --git a/sysconfig/network-scripts/network-functions-ipv6 b/sysconfig/network-scripts/network-functions-ipv6 index f9f87d29..6b4441a8 100644 --- a/sysconfig/network-scripts/network-functions-ipv6 +++ b/sysconfig/network-scripts/network-functions-ipv6 @@ -5,16 +5,12 @@ # Taken from: # (P) & (C) 1997-2001 by Peter Bieringer # -# Version: 2001-03-03b +# Version: 2001-05-22d # # Extended address detection is enabled, if 'ipv6calc' is installed # Available here: http://www.bieringer.de/linux/IPv6/tools/index.html#ipv6calc # -# Known bugs: -# sit0 will not be shutdowned, if an additional IPv6 address was manually added to this device -# -# Filter tags (for stripping, empty lines following here if all is stripped) @@ -24,85 +20,102 @@ # 1 = error occurs # 2 = not enabled, i.e. no IPv6 kernel support or switched off by configuration -##### Test for "ipv6calc" (can be used for better duplicate address detection) +##### Test for "ipv6calc" (used for better existing address detection) EXISTS_ipv6calc=no if which ipv6calc >/dev/null 2>&1; then - EXISTS_ipv6calc=yes + # do checks, whether ipv6calc does what was expected + if ipv6calc --if_inet62addr 3ffe04000100f1010000000000000001 40 | grep -q -v '3ffe:400:100:f101::1/64'; then + false + elif ipv6calc --addr2if_inet6 3ffe:400:100::1/64 | grep -q -v '3ffe0400010000000000000000000001 00 40'; then + false + else + EXISTS_ipv6calc=yes + fi else - true + false fi ##### Test for IPv6 capabilites +# $1: (optional) testflag: currently supported: "testonly" (do not load a module) +test_ipv6() { + local testflag=$1 -function test_ipv6() -{ # Test for IPv6 enabled kernel if ! [ -f /proc/net/if_inet6 ]; then - modprobe ipv6 - - if ! [ -f /proc/net/if_inet6 ]; then - echo $"Kernel is not compiled with IPv6 support" + if [ "$testflag" = "testonly" ]; then return 2 + else + modprobe ipv6 + + if ! [ -f /proc/net/if_inet6 ]; then + echo $"Kernel is not compiled with IPv6 support" + return 2 + fi fi fi + if [ ! -d /proc/sys/net/ipv6/conf/ ]; then + # IPv6 related proc directory doesn't exist + return 2 + fi + + if ! which ip 2>&1 >/dev/null; then + echo $"Utility 'ip' (iproute-package) doesn't exist or isn't executable - non-NBMA-styled tunneling setup won't work!" + return 2 + fi + return 0 } -##### Control IPv6 forwarding -# Display usage -function forwarding_ipv6_usage() { - echo $"Usage: $0 yes|no [device]" + +##### Get version of this function libary +getversion_ipv6_functions() { + local version_ipv6_functions="`cat /etc/sysconfig/network-scripts/network-functions-ipv6 | grep "^# Version:" | awk '{ print $3 }' | sed 's/-//g' | sed 's/[A-Za-z]*$//g'`" + echo $version_ipv6_functions } +##### Control IPv6 forwarding # Control IPv6 forwarding # $1: control [yes|no|on|off] -# $2: network device (if not given, global IPv6 forwarding is set) -function forwarding_ipv6() { - fw_control=$1 - fw_device=$2 # maybe empty +# $2: network device (if not given, global IPv6 forwarding is set) [OBSOLETE] +forwarding_ipv6() { + local fw_control=$1 + local fw_device=$2 # maybe empty if [ -z "$fw_control" ]; then - echo $"Missing parameter 'forwarding control'" - forwarding_ipv6_usage + echo $"Missing parameter 'forwarding control' (arg 1)" return 1 fi if ! [ "$fw_control" = "yes" -o "$fw_control" = "no" -o "$fw_control" = "on" -o "$fw_control" = "off" ]; then - echo $"Don't understand forwarding control parameter '$fw_control'" - forwarding_ipv6_usage + echo $"Don't understand forwarding control parameter '$fw_control' (arg 1)" return 1 fi - # Device "lo" need no IPv6 configuration - if [ "$fw_device" = "lo" ]; then - return 0; - fi - # Run IPv6 test - test_ipv6 || return + test_ipv6 || return 2 if [ "$fw_control" = "yes" -o "$fw_control" = "on" ]; then - status=1 + local status=1 else - status=0 + local status=0 fi # Global control? (if no device is given) if [ -z "$fw_device" ]; then - sysctl -w net.ipv6.conf.all.forwarding=$status >/dev/null 2>&1 + sysctl -w net.ipv6.conf.all.forwarding=$status >/dev/null fi - # Per device control + # Per device control (not implemented in kernel) if [ ! -z "$fw_device" ]; then - sysctl -w net.ipv6.conf.$fw_device.forwarding=$status >/dev/null 2>&1 + echo $"IPv6 forwarding per device cannot be controlled via sysctl - use netfilter6 instead!" fi } @@ -110,112 +123,144 @@ function forwarding_ipv6() { ##### Static IPv6 route configuration -# Display usage -function ifupdown_ipv6_route_usage() { - echo $"Usage: $0 IPv6-network IPv6-gateway [device]" -} - # Set static IPv6 route # $1: IPv6 network to route -# $2: IPv6 gateway over which $1 should be routed +# $2: IPv6 gateway over which $1 should be routed (if "::", gw will be skipped) # $3: Interface (optional) -function ifup_ipv6_route() { - networkipv6=$1 - gatewayipv6=$2 - device=$3 # maybe empty +ifup_ipv6_route() { + local networkipv6=$1 + local gatewayipv6=$2 + local device=$3 # maybe empty if [ -z "$networkipv6" ]; then - echo $"Missing parameter 'IPv6-network'" - ifupdown_ipv6_route_usage + echo $"Missing parameter 'IPv6-network' (arg 1)" return 1 fi if [ -z "$gatewayipv6" ]; then - echo $"Missing parameter 'IPv6-gateway'" - ifupdown_ipv6_route_usage + echo $"Missing parameter 'IPv6-gateway' (arg 2)" return 1 fi - # Device "lo" need no IPv6 configuration - if [ "$device" = "lo" ]; then - return 0; - fi - # Run IPv6 test - test_ipv6 || return + test_ipv6 || return 2 + + # Test, whether given IPv6 address is valid + if ! testipv6_valid $networkipv6; then + return 2 + fi + if ! testipv6_valid $gatewayipv6; then + return 2 + fi if [ -z "$device" ]; then - output="`LC_ALL=C route -A inet6 add $networkipv6 gw $gatewayipv6 2>&1`" - if [ $? -ne 0 ]; then - if echo $output | grep -i -q 'SIOCADDRT: File exists'; then - true - else - echo $output - fi - fi + local output="`LC_ALL=C route -A inet6 add $networkipv6 gw $gatewayipv6 2>&1`" else - output="`LC_ALL=C route -A inet6 add $networkipv6 gw $gatewayipv6 dev $device 2>&1`" - if [ $? -ne 0 ]; then - if echo $output | grep -i -q 'SIOCADDRT: File exists'; then - true - else - echo $output - fi - fi + if [ "$gatewayipv6" = "::" ]; then + local output="`LC_ALL=C route -A inet6 add $networkipv6 dev $device 2>&1`" + else + local output="`LC_ALL=C route -A inet6 add $networkipv6 gw $gatewayipv6 dev $device 2>&1`" + fi + fi + + if [ $? -ne 0 ]; then + if echo $output | grep -i -q 'SIOCADDRT: File exists'; then + true + else + echo $output + return 2 + fi fi + return 0 } -# Delete static IPv6 route +# Delete a static IPv6 route # $1: IPv6 network to route -# $2: IPv6 gateway over which $1 should be routed +# $2: IPv6 gateway over which $1 should be routed (if "::", gw will be skipped) # $3: Interface (optional) -function ifdown_ipv6_route() { - networkipv6=$1 - gatewayipv6=$2 - device=$3 # maybe empty +ifdown_ipv6_route() { + local networkipv6=$1 + local gatewayipv6=$2 + local device=$3 # maybe empty if [ -z "$networkipv6" ]; then - echo $"Missing parameter 'IPv6-network'" - ifup_ipv6_route_usage + echo $"Missing parameter 'IPv6-network' (arg 1)" return 1 fi if [ -z "$gatewayipv6" ]; then - echo $"Missing parameter 'IPv6-gateway'" - ifup_ipv6_route_usage + echo $"Missing parameter 'IPv6-gateway' (arg 2)" return 1 fi - # Device "lo" need no IPv6 configuration - if [ "$device" = "lo" ]; then - return 0; - fi - # Run IPv6 test - test_ipv6 || return + test_ipv6 || return 2 + + # Test, whether given IPv6 address is valid + if ! testipv6_valid $networkipv6; then + return 2 + fi + if ! testipv6_valid $gatewayipv6; then + return 2 + fi if [ -z "$device" ]; then - output="`LC_ALL=C route -A inet6 del $networkipv6 gw $gatewayipv6 2>&1`" - if [ $? -ne 0 ]; then - if echo $output | grep -i -q 'SIOCDELRT: No such process'; then - true - else - echo $output - fi - fi + local output="`LC_ALL=C route -A inet6 del $networkipv6 gw $gatewayipv6 2>&1`" else - output="`LC_ALL=C route -A inet6 del $networkipv6 gw $gatewayipv6 dev $device 2>&1`" - if [ $? -ne 0 ]; then - if echo $output | grep -i -q 'SIOCDELRT: No such process'; then - true - else - echo $output + if [ "$gatewayipv6" = "::" ]; then + local output="`LC_ALL=C route -A inet6 del $networkipv6 dev $device 2>&1`" + else + local output="`LC_ALL=C route -A inet6 del $networkipv6 gw $gatewayipv6 dev $device 2>&1`" + fi + fi + + if [ $? -ne 0 ]; then + if echo $output | grep -i -q 'SIOCDELRT: No such process'; then + true + else + echo $output + return 2 + fi + fi + + return 0 +} + +# Delete all static IPv6 routes through a given interface +# $1: Interface +# $2: Gateway match (optional) +ifdown_ipv6_route_all() { + local device=$1 + local gatewaymatch=$2 + + if [ -z "$device" ]; then + echo $"Missing parameter 'device' (arg 1)" + return 1 + fi + + # Run IPv6 test + test_ipv6 || return 2 + + + # Get all IPv6 routes through given interface and remove them + LC_ALL=C route -A inet6 -n | grep "$device\W*$" | while read ipv6net nexthop flags metric ref use iface args; do + if [ "$iface" = "$device" ]; then + if [ ! -z "$gatewaymatch" ]; then + # Test if given gateway matches + if [ "$gatewaymatch" != "$nexthop" ]; then + # No match, take next + continue fi fi - fi + # Only non addrconf (automatic installed) routes should be removed + if echo $flags | grep -v -q "A"; then + local output="`LC_ALL=C route -A inet6 del $ipv6net gw $nexthop dev $iface 2>&1`" + fi + fi + done } @@ -223,107 +268,121 @@ function ifdown_ipv6_route() { ##### automatic tunneling configuration ## Configure automatic tunneling up -function ifup_ipv6_autotunnel() { - +ifup_ipv6_autotunnel() { # Run IPv6 test - test_ipv6 || return + test_ipv6 || return 2 # enable IPv6-over-IPv4 tunnels - if LC_ALL=C ifconfig sit0 | grep -q "UP "; then + if test_interface_status sit0; then # already up, do nothing true else # basic tunnel device to up ifconfig sit0 up - # Switch on forwarding - forwarding_ipv6 on sit0 + # Test, whether "up" has worked + if ! test_interface_status sit0; then + echo $"Tunnel device 'sit0' enabling didn't work - FATAL ERROR!" + return 2 + fi + + # Set sysctls proper (regardless "default") + sysctl -w net.ipv6.conf.sit0.forwarding=1 >/dev/null + sysctl -w net.ipv6.conf.sit0.accept_ra=0 >/dev/null + sysctl -w net.ipv6.conf.sit0.accept_redirects=0 >/dev/null fi + return 0 } ## Configure automatic tunneling down -function ifdown_ipv6_autotunnel() { - +ifdown_ipv6_autotunnel() { # Run IPv6 test - test_ipv6 || return + test_ipv6 || return 2 - if LC_ALL=C ifconfig sit0 | grep -q "UP "; then + if test_interface_status sit0; then # still up? # disable IPv6-over-IPv4 tunnels (if a tunnel is no longer up) - if LC_ALL=C route -n -A inet6 -n | grep sit0 | awk '{ print $2 }' | grep -v -q "^::$"; then + if LC_ALL=C route -A inet6 -n | grep "sit0\W*$" | awk '{ print $2 }' | grep -v -q "^::$"; then # still existing routes, skip shutdown of sit0 true - elif LC_ALL=C ifconfig sit0 | grep 'inet6 addr:' | awk '{ print $3 }' | grep -v -q '^::'; then + elif LC_ALL=C ip addr show dev sit0 | grep inet6 | awk '{ print $2 }' | grep -v -q '^::'; then # still existing IPv6 addresses, skip shutdown of sit0 true else # basic tunnel device to down - # Switch off forwarding - forwarding_ipv6 off sit0 + # Set sysctls proper + sysctl -w net.ipv6.conf.sit0.forwarding=0 >/dev/null + sysctl -w net.ipv6.conf.sit0.accept_ra=0 >/dev/null + sysctl -w net.ipv6.conf.sit0.accept_redirects=0 >/dev/null ifconfig sit0 down + + # Test, whether "down" has worked + if test_interface_status sit0; then + echo $"Tunnel device 'sit0' is still up - FATAL ERROR!" + return 2 + fi fi fi + return 0 } -##### static tunneling configuration - -function ifupdown_ipv6_tunnel_usage() { - echo $"Usage: $0 interfacename IPv4-tunneladdress IPv6-route" -} - +##### static NBMA-styled tunnel configuration ## Configure static tunnels up # $1: Interface (not needed - dummy) # $2: IPv4 address of foreign tunnel # $3: IPv6 route through this tunnel -function ifup_ipv6_tunnel() { - device=$1 - addressipv4tunnel=$2 - routeipv6=$3 +ifup_ipv6_tunnel() { + local device=$1 + local addressipv4tunnel=$2 + local routeipv6=$3 if [ -z "$device" ]; then - echo $"Missing parameter 'device'" - ifupdown_ipv6_tunnel_usage + echo $"Missing parameter 'device' (arg 1)" return 1 fi if [ -z "$addressipv4tunnel" ]; then - echo $"Missing parameter 'IPv4-tunneladdress'" - ifupdown_ipv6_tunnel_usage + echo $"Missing parameter 'IPv4-tunneladdress' (arg 2)" return 1 fi if [ -z "$routeipv6" ]; then - echo $"Missing parameter 'IPv6-route'" - ifupdown_ipv6_tunnel_usage + echo $"Missing parameter 'IPv6-route' (arg 3)" return 1 fi - + # Run IPv6 test - test_ipv6 || return + test_ipv6 || return 2 + + # Test, whether given IPv6 address is valid + if ! testipv6_valid $routeipv6; then + return 2 + fi + # enable general IPv6-over-IPv4 tunneling ifup_ipv6_autotunnel + if [ $? -ne 0 ]; then + return 2 + fi - # Set up a tunnel - output="`LC_ALL=C route -A inet6 add $routeipv6 gw ::$addressipv4tunnel dev sit0 2>&1`" + # Set up a tunnel + ifup_ipv6_route $routeipv6 ::$addressipv4tunnel sit0 if [ $? -ne 0 ]; then - if echo $output | grep -i -q 'SIOCADDRT: File exists'; then - true - else - echo $output - fi + return 2 fi + return 0 } @@ -331,41 +390,37 @@ function ifup_ipv6_tunnel() { # $1: Interface (not used - dummy) # $2: IPv4 address of foreign tunnel # $3: IPv6 route through this tunnel -function ifdown_ipv6_tunnel() { - device=$1 - addressipv4tunnel=$2 - routeipv6=$3 +ifdown_ipv6_tunnel() { + local device=$1 + local addressipv4tunnel=$2 + local routeipv6=$3 if [ -z "$device" ]; then - echo $"Missing parameter 'device'" + echo $"Missing parameter 'device' (arg 1)" ifupdown_ipv6_tunnel_usage return 1 fi if [ -z "$addressipv4tunnel" ]; then - echo $"Missing parameter 'IPv4-tunneladdress'" + echo $"Missing parameter 'IPv4-tunnel address' (arg 2)" ifupdown_ipv6_tunnel_usage return 1 fi if [ -z "$routeipv6" ]; then - echo $"Missing parameter 'IPv6-route'" + echo $"Missing parameter 'IPv6-route' (arg 3)" ifupdown_ipv6_tunnel_usage return 1 fi # Run IPv6 test - test_ipv6 || return + test_ipv6 || return 2 - # Set up a tunnel - output="`LC_ALL=C route -A inet6 del $routeipv6 gw ::$addressipv4tunnel dev sit0 2>&1`" + # Delete a NBMA-styled tunnel + ifdown_ipv6_route $routeipv6::$addressipv4tunnel sit0 if [ $? -ne 0 ]; then - if echo $output | grep -i -q 'SIOCDELRT: No such process'; then - true - else - echo $output - fi + return 2 fi # disable IPv6-over-IPv4 tunneling (if no longer a tunnel is up) @@ -377,23 +432,26 @@ function ifdown_ipv6_tunnel() { ## Remove all IPv6 tunnels for a given tunnel endpoint # $1: Interface (not used - dummy) # $2: IPv4-tunneladdress -function ifdown_ipv6_tunnel_all() { - idtuall_device=$1 - idtuall_tunnel=$2 +ifdown_ipv6_tunnel_all() { + local idtuall_device=$1 + local idtuall_tunnel=$2 if [ -z "$idtuall_device" ]; then - echo $"Missing parameter 'device'" - echo $"Usage: ifdown_ipv6_tunnel_all interfacename IPv4-tunneladdress" + echo $"Missing parameter 'device' (arg 1)" return 1 fi if [ -z "$idtuall_tunnel" ]; then - echo $"Missing parameter 'IPv4-tunneladdress'" - echo $"Usage: ifdown_ipv6_tunnel_all interfacename IPv4-tunneladdress" + echo $"Missing parameter 'IPv4-tunneladdress' (arg 2)" return 1 fi + + # Run IPv6 test + test_ipv6 || return 2 + + # Get all IPv6 routes through given interface and remove them - LC_ALL=C route -n -A inet6 | grep "::$idtuall_tunnel" | while read ipv6net nexthop flags metric ref use iface args; do + LC_ALL=C route -A inet6 -n | grep "::$idtuall_tunnel" | while read ipv6net nexthop flags metric ref use iface args; do if [ "::$idtuall_tunnel" = "$nexthop" ]; then if echo $flags | grep -v -q "A"; then # Only non addrconf (automatic installed) routes should be removed @@ -401,6 +459,10 @@ function ifdown_ipv6_tunnel_all() { fi fi done + + # disable IPv6-over-IPv4 tunneling (if no longer a tunnel is up) + ifdown_ipv6_autotunnel + return 0 } @@ -409,13 +471,13 @@ function ifdown_ipv6_tunnel_all() { # $2: Address to test (without prefix) # $3: Prefix of address $1 # return values: 1:problem, 10:not exists, 11:exits -function test_ipv6_addrs_exists () { - testdevice=$1 - testaddr=$2 - testprefix=$3 +test_ipv6_address_exists() { + local testdevice=$1 + local testaddr=$2 + local testprefix=$3 if [ -z "$testaddr" ]; then - echo $"Missing parameter 'IPv6AddrToTest'" + echo $"Missing parameter 'IPv6AddrToTest' (arg 1)" return 1 fi @@ -423,16 +485,16 @@ function test_ipv6_addrs_exists () { if [ "$EXISTS_ipv6calc" = "yes" ]; then # Using ipv6calc and compare against /proc/net/if_inet6 - convertresult="`LC_ALL=C ipv6calc --addr2if_inet6 $testaddr/$testprefix`" + local convertresult="`LC_ALL=C ipv6calc --addr2if_inet6 $testaddr/$testprefix`" # Split in address, scope and prefix length - test_addr="`echo $convertresult | awk '{ print $1 }'`" - test_scope="`echo $convertresult | awk '{ print $2 }'`" - test_prefixlength="`echo $convertresult | awk '{ print $3 }'`" + local test_addr="`echo $convertresult | awk '{ print $1 }'`" + local test_scope="`echo $convertresult | awk '{ print $2 }'`" + local test_prefixlength="`echo $convertresult | awk '{ print $3 }'`" if [ -z "$test_prefixlength" ]; then - testresult="`grep "$test_addr .. .. $test_scope .." /proc/net/if_inet6 | grep $testdevice$`" + local testresult="`grep "$test_addr .. .. $test_scope .." /proc/net/if_inet6 | grep $testdevice$`" else - testresult="`grep "$test_addr .. $test_prefixlength $test_scope .." /proc/net/if_inet6 | grep $testdevice$`" + local testresult="`grep "$test_addr .. $test_prefixlength $test_scope .." /proc/net/if_inet6 | grep $testdevice$`" fi if [ ! -z "$testresult" ]; then return 11 @@ -440,8 +502,8 @@ function test_ipv6_addrs_exists () { return 10 fi else - # low budget version, only works if given address is in equal form like ifconfig displays - testresult="`LC_ALL=C ifconfig $testdevice | grep "inet6 addr:" | grep -i ": $testaddr/$testprefix" | awk '{ print $3 }'`" + # low budget version, only works if given address is in equal form like "ip" displays + local testresult="`LC_ALL=C ip addr show dev $testdevice | grep inet6 | awk '{ print $2 }' | grep -i "^$testaddr/$testprefix$"`" if [ ! -z "$testresult" ]; then return 11 else @@ -451,64 +513,56 @@ function test_ipv6_addrs_exists () { } ##### Interface configuration -function ifupdown_ipv6_usage() { - echo $"Usage: $0 interfacename IPv6-address/IPv6-prefixlength" -} ## Add an IPv6 address for given interface # $1: Interface # $2: IPv6 address -function ifup_ipv6_real() { - device=$1 - address=$2 +ifup_ipv6_real() { + local device=$1 + local address=$2 if [ -z "$device" ]; then - echo $"Missing parameter 'device'" + echo $"Missing parameter 'device' (arg 1)" ifupdown_ipv6_usage return 1 fi - # Device "lo" need no IPv6 configuration - if [ "$device" = "lo" ]; then - return 0; - fi - if [ -z "$address" ]; then - echo $"Missing parameter 'IPv6-address'" + echo $"Missing parameter 'IPv6-address' (arg 2)" ifupdown_ipv6_usage return 1 fi + # Run IPv6 test + test_ipv6 || return 2 + + # Test, whether given IPv6 address is valid + if ! testipv6_valid $address; then + return 2 + fi + # Test status of interface - if LC_ALL=C ifconfig $device | grep -q "UP "; then - # Interface is up - true + if test_interface_status $device; then + # Interface is already up + true else # no IPv4 for this interface, interface is still down, do up ... - ifconfig $device up - fi - - # Extract address parts - prefixlength_implicit="`echo $address | awk -F/ '{ print $2 }'`" - address_implicit="`echo $address | awk -F/ '{ print $1 }'`" + ifconfig $device up - # Test for prefix length - if [ -z "$prefixlength_implicit" ]; then - echo $"Missing 'prefix length' for given address" - ifupdown_ipv6_usage - return 1 - elif [ $prefixlength_implicit -lt 0 -o $prefixlength_implicit -gt 128 ]; then - echo $"'prefix length' on given address is out of range (0-128)" - ifupdown_ipv6_usage - return 1 + # Test, whether "up" has worked + if ! test_interface_status $device; then + echo $"Device '$device' enabling didn't work - FATAL ERROR!" + return 2 + fi fi - # Run IPv6 test - test_ipv6 || return + # Extract address parts + local prefixlength_implicit="`echo $address | awk -F/ '{ print $2 }'`" + local address_implicit="`echo $address | awk -F/ '{ print $1 }'`" # Only add, if address do not already exist - test_ipv6_addrs_exists $device $address_implicit $prefixlength_implicit + test_ipv6_address_exists $device $address_implicit $prefixlength_implicit retval=$? if [ $retval -lt 10 ]; then return 2 @@ -520,94 +574,72 @@ function ifup_ipv6_real() { ifconfig $device add $address || return 2 fi + return 0 } ## Remove all IPv6 routes and addresses for given interface # cleanup to prevent kernel crashes # $1: Interface -function ifdown_ipv6_real_all() { - idall_device=$1 +ifdown_ipv6_real_all() { + local device=$1 - if [ -z "$idall_device" ]; then - echo $"Missing parameter 'device'" - echo $"Usage: ifdown_ipv6_real_all interfacename" + if [ -z "$device" ]; then + echo $"Missing parameter 'device' (arg 1)" return 1 fi - # Get all IPv6 routes through given interface and remove them - LC_ALL=C route -n -A inet6 | grep $idall_device | while read ipv6net nexthop flags metric ref use iface args; do - if [ "$idall_device" = "$iface" ]; then - if echo $flags | grep -v -q "A"; then - # Only non addrconf (automatic installed) routes should be removed - ifdown_ipv6_route $ipv6net $nexthop $iface - fi + # Run IPv6 test + test_ipv6 || return 2 + + + # Remove all IPv6 routes through this device (but not "lo") + if [ "$device" != "lo" ]; then + ip -6 route flush dev $device >/dev/null 2>&1 fi - done - - # Get all IPv6 addresses assigned to given interface and remove them - if [ "$EXISTS_ipv6calc" = "yes" ]; then - grep $idall_device$ /proc/net/if_inet6 | while read hexaddr dummy1 hexprefixlenth hexscope device args; do - if [ "$hexscope" != "20" ]; then - ipv6addr="`ipv6calc --if_inet62addr $hexaddr $hexprefixlenth`" - ifdown_ipv6_real $idall_device $ipv6addr - fi - done - else - LC_ALL=C ifconfig $idall_device | grep "inet6 addr:" | while read dummy1 dummy2 ipv6addr scope args; do - if [ "$scope" != "Scope:Link" ]; then - ifdown_ipv6_real $idall_device $ipv6addr - fi - done - fi + + # Remove all IPv6 addresses on this interface + ip -6 addr flush dev $device >/dev/null 2>&1 + + return 0 } + ## Remove an IPv6 address on given interface # $1: Interface # $2: IPv6 address -function ifdown_ipv6_real() { - device=$1 - address=$2 +ifdown_ipv6_real() { + local device=$1 + local address=$2 if [ -z "$device" ]; then - echo $"Missing parameter 'device'" + echo $"Missing parameter 'device' (arg 1)" ifupdown_ipv6_usage return 1 fi - # Device "lo" need no IPv6 configuration - if [ "$device" = "lo" ]; then - return 0; - fi - if [ -z "$address" ]; then - echo $"Missing parameter 'IPv6-address'" + echo $"Missing parameter 'IPv6-address' (arg 2)" ifupdown_ipv6_usage return 1 fi - # Extract address parts - prefixlength_implicit="`echo $address | awk -F/ '{ print $2 }'`" - address_implicit="`echo $address | awk -F/ '{ print $1 }'`" + # Run IPv6 test + test_ipv6 || return 2 - # Test for prefix length - if [ -z "$prefixlength_implicit" ]; then - echo $"Missing 'prefix length' for given address" - ifupdown_ipv6_usage - return 1 - elif [ $prefixlength_implicit -lt 0 -o $prefixlength_implicit -gt 128 ]; then - echo $"'prefix length' on given address is out of range (0-128)" - ifupdown_ipv6_usage - return 1 + # Test, whether given IPv6 address is valid + if ! testipv6_valid $address; then + return 2 fi - # Run IPv6 test - test_ipv6 || return + # Extract address parts + local prefixlength_implicit="`echo $address | awk -F/ '{ print $2 }'`" + local address_implicit="`echo $address | awk -F/ '{ print $1 }'`" # Only remove, if address exists and is not link-local (prevents from kernel crashing) - test_ipv6_addrs_exists $device $address_implicit $prefixlength_implicit - retval=$? + test_ipv6_address_exists $device $address_implicit $prefixlength_implicit + local retval=$? if [ $retval -lt 10 ]; then return 2 fi @@ -618,5 +650,408 @@ function ifdown_ipv6_real() { true fi + return 0 } + +##### Some address test functions + +## Test a given IPv6 address for valid +# $1: IPv6 address +# Return code =0:valid 1:not valid 2:general problem +testipv6_valid() { + local testipv6addr_valid=$1 + + + if [ -z "$testipv6addr_valid" ]; then + # nothing for testing + return 2 + fi + + # Extract parts + local prefixlength_implicit="`echo $testipv6addr_valid | awk -F/ '{ print $2 }'`" + local address_implicit="`echo $testipv6addr_valid | awk -F/ '{ print $1 }'`" + + if [ "$EXISTS_ipv6calc" = "yes" ]; then + if ! ipv6calc --addr2uncompaddr $testipv6addr_valid >/dev/null 2>&1; then + echo $"Given IPv6 address '$testipv6addr_valid' is not valid" + return 1 + fi + else + # Test for a valid format + if ! echo "$address_implicit" | egrep -q '^[a-fA-F0-9:\.]*$'; then + echo $"Given IPv6 address '$testipv6addr_valid' is not valid" + return 1 + fi + fi + + # Test for prefix length + if [ -z "$prefixlength_implicit" ]; then + if echo "$testipv6addr_valid" | grep "/$"; then + # Trailing "/", but no value + echo $"Missing 'prefix length' for given address ''$testipv6addr_valid" + return 1 + else + return 0 + fi + elif [ $prefixlength_implicit -lt 0 -o $prefixlength_implicit -gt 128 ]; then + echo $"'prefix length' on given address '$testipv6addr_valid' is out of range (0-128)" + return 1 + fi + + return 0 +} + + + + +## Test a given IPv4 address for not a private but unicast one +# $1: IPv4 address +# Return code =0:ok 1:private or not unicast 2:general problem +testipv4_globalusable() { + local testipv4addr_globalusable=$1 + + + if [ -z "$testipv4addr_globalusable" ]; then + # nothing for testing + return 2 + fi + + + # Test for a globally usable IPv4 address now + # test 0.0.0.0/8 + ipcalc --network $testipv4addr_globalusable 255.0.0.0 | grep -q "NETWORK=0\.0\.0\.0" && return 1 + # test 10.0.0.0/8 (private) + ipcalc --network $testipv4addr_globalusable 255.0.0.0 | grep -q "NETWORK=10\.0\.0\.0" && return 1 + # test 127.0.0.0/8 (loopback) + ipcalc --network $testipv4addr_globalusable 255.0.0.0 | grep -q "NETWORK=127\.0\.0\.0" && return 1 + # test 169.254.0.0/16 (DHCP link local) + ipcalc --network $testipv4addr_globalusable 255.255.0.0 | grep -q "NETWORK=169\.254\.0\.0" && return 1 + # test 172.16.0.0/12 (private) + ipcalc --network $testipv4addr_globalusable 255.240.0.0 | grep -q "NETWORK=172\.16\.0\.0" && return 1 + # test 192.168.0.0/16 (private) + ipcalc --network $testipv4addr_globalusable 255.255.0.0 | grep -q "NETWORK=192\.168\.0\.0" && return 1 + # test 224.0.0.0/3 (multicast and reserved, broadcast) + ipcalc --network $testipv4addr_globalusable 224.0.0.0 | grep -q "NETWORK=224\.0\.0\.0" && return 1 + + return 0 +} + + +## Test a given device for status +# $1: device name +# Return code =0:UP 1:not UP 2:not exists +test_interface_status() { + local device=$1 + + if [ -z "$device" ]; then + echo $"Missing parameter 'device'" + echo $"Usage: ifdown_ipv6to4_all interfacename" + return 1 + fi + + # Test if device exists + if ! LC_ALL=C ifconfig $device >/dev/null 2>&1 ; then + return 2 + fi + + # Test if device is up + if LC_ALL=C ifconfig $device 2>&1 | grep -q "UP "; then + return 0 + else + return 1 + fi +} + + +## Build 6to4 prefix +# $1: IPv4 address +# RetVal: 6to4address +# Returncode 0=ok 1=failure 2=general problem +create6to4prefix() { + local ipv4addr=$1 + + + local major1="`echo $ipv4addr | awk -F. '{ print $1 }'`" + local minor1="`echo $ipv4addr | awk -F. '{ print $2 }'`" + local major2="`echo $ipv4addr | awk -F. '{ print $3 }'`" + local minor2="`echo $ipv4addr | awk -F. '{ print $4 }'`" + + if [ -z "$major1" -o -z "$minor1" -o -z "$major2" -o -z "$minor2" ]; then + return 2 + fi + + if [ $major1 -eq 0 ]; then + local block1="`printf "%x" $minor1`" + else + local block1="`printf "%x%02x" $major1 $minor1`" + fi + if [ $major2 -eq 0 ]; then + local block2="`printf "%x" $minor2`" + else + local block2="`printf "%x%02x" $major2 $minor2`" + fi + + local prefix6to4="2002:$block1:$block2" + + echo "$prefix6to4" + return 0 +} + + +##### 6to4 tunneling setup + +## Configure 6to4 tunneling up +# $1: Interface (not needed - dummy) +# $2: global IPv4 address of local interface +# $3: IPv6 suffix for 6to4 prefix (optional, default is "1") +# ReturnCodes 0=ok 1=failure 2=general problem +ifup_ipv6to4() { + local device=$1 # dummy + local localipv4=$2 + local localipv6to4suffix=$3 + + if [ -z "$device" ]; then + echo $"Missing parameter 'device' (arg 1)" + ifupdown_ipv6to4_usage + return 1 + fi + + if [ -z "$localipv4" ]; then + echo $"Missing parameter 'local IPv4 address' (arg 2)" + ifupdown_ipv6to4_usage + return 1 + fi + + # Run IPv6 test + test_ipv6 || return 2 + + + # generate 6to4 address + local prefix6to4="`create6to4prefix $localipv4`" + if [ $? -ne 0 -o -z "$prefix6to4" ]; then + return 2 + fi + + if [ -z "$localipv6to4suffix" ]; then + local address6to4="${prefix6to4}::1/48" + else + local address6to4="${prefix6to4}::${localipv6to4suffix}/48" + fi + + # enable general IPv6-over-IPv4 tunneling + ifup_ipv6_autotunnel + + ifup_ipv6_real sit0 $address6to4 + if [ $? -ne 0 ]; then + return 2 + fi + + return 0 +} + + +## Configure all 6to4 tunneling down +# $1: Interface (not needed - dummy) +# ReturnCodes 0=ok 1=failure 2=general problem +ifdown_ipv6to4_all() { + local device=$1 # dummy + + if [ -z "$device" ]; then + echo $"Missing parameter 'device' (arg 1)" + return 1 + fi + + # Run IPv6 test + test_ipv6 || return 2 + + + # Get all configured 6to4 addresses + LC_ALL=C ip addr show dev sit0 | grep inet6 | awk '{ print $2 }' | grep "^2002:" | while read ipv6to4addr; do + # And delete them + ifdown_ipv6_real sit0 $ipv6to4addr + done + + # try to disable general IPv6-over-IPv4 tunneling + ifdown_ipv6_autotunnel + +} + + +## Configure 6to4 tunneling down +# $1: Interface (not needed - dummy) +# $2: global IPv4 address of local interface +# ReturnCodes 0=ok 1=failure 2=general problem +ifdown_ipv6to4() { + local device=$1 # dummy + local localipv4=$2 + + if [ -z "$device" ]; then + echo $"Missing parameter 'device' (arg 1)" + return 1 + fi + + if [ -z "$localipv4" ]; then + echo $"Missing parameter 'local IPv4 address' (arg 2)" + return 1 + fi + + # Run IPv6 test + test_ipv6 || return 2 + + + # generate 6to4 address + local prefix6to4="`create6to4prefix $localipv4`" + echo $"Generated 6to4 prefix '$prefix6to4' from '$localipv4'" + if [ $? -ne 0 -o -z "$prefix6to4" ]; then + return 2 + fi + + if [ -z "$localipv6to4suffix" ]; then + local address6to4="$prefix6to4::1/48" + else + local address6to4="${prefix6to4}::${localipv6to4suffix}/48" + fi + + ifdown_ipv6_real sit0 $address6to4 + if [ $? -ne 0 ]; then + return 2 + fi + + # try to disable general IPv6-over-IPv4 tunneling + ifdown_ipv6_autotunnel + if [ $? -ne 0 ]; then + return 2 + fi + + return 0 +} + + +##### static tunnel device configuration + +## Configure a static tunnel device up +# $1: Interface +# $2: IPv4 address of foreign tunnel +# $3: Local IPv6 address of a P-t-P tunnel (optional) +ifup_ipv6_tunneldev() { + local device=$1 + local addressipv4tunnel=$2 + local addressipv6local=$3 + + if [ -z "$device" ]; then + echo $"Missing parameter 'device' (arg 1)" + return 1 + fi + + if [ -z "$addressipv4tunnel" ]; then + echo $"Missing parameter 'IPv4-tunneladdress' (arg 2)" + return 1 + fi + + # Run IPv6 test + test_ipv6 || return 2 + + + + if ! test_interface_status $device; then + # Get default TTL + local ttldefault="`sysctl net.ipv4.ip_default_ttl | awk '{ print $3 }'`" + if [ -z "$ttldefault" ]; then + local ttldefault=64 + fi + + # Test whether remote IPv4 address was already applied to another tunnel (does not catch IPv4 addresses with leading 0's) + LC_ALL=C ip tunnel show | grep $addressipv4tunnel | while read dev type tag remote tag local tag ttl rest; do + local devnew="`echo $dev | sed 's/:$//g'`" + if [ "$remote" = "$addressipv4tunnel" ]; then + echo $"Given remote address '$addressipv4tunnel' on tunnel device '$device' is already configured on device '$devnew' - FATAL ERROR!" + return 2 + fi + done + if [ $? -ne 0 ]; then + return 2 + fi + + ip tunnel add $device mode sit ttl $ttldefault remote $addressipv4tunnel + + # Test, whether "ip tunnel show" works without error + ip tunnel show $device >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo $"Tunnel device '$device' creation didn't work - ERROR!" + return 2 + fi + + # Test, whether "ip tunnel show" reports valid content + if ! ip tunnel show $device | grep -q "remote"; then + echo $"Tunnel device '$device' creation didn't work - ERROR!" + return 2 + fi + + ifconfig $device up + + # Test, whether creation did worked + if ! test_interface_status $device; then + echo $"Tunnel device '$device' bringing up didn't work - ERROR!" + return 2 + fi + + # Set sysctls proper (regardless "default") + sysctl -w net.ipv6.conf.$device.forwarding=1 >/dev/null + sysctl -w net.ipv6.conf.$device.accept_ra=0 >/dev/null + sysctl -w net.ipv6.conf.$device.accept_redirects=0 >/dev/null + + if [ ! -z "$addressipv6local" ]; then + # Setup P-t-P address + ifup_ipv6_real $device $addressipv6local + if [ $? -ne 0 ]; then + return 2 + fi + fi + else + false + fi + + return 0 +} + + +## Configure a static tunnel device down +# $1: Interface +ifdown_ipv6_tunneldev() { + local device=$1 + + if [ -z "$device" ]; then + echo $"Missing parameter 'device' (arg 1)" + return 1 + fi + + # Run IPv6 test + test_ipv6 || return 2 + + + if test_interface_status $device; then + # Shut down tunnel + ifdown_ipv6_real_all $device + else + if [ "$device" != "sit0" ]; then + false + fi + fi + + if [ "$device" != "sit0" ]; then + if ip tunnel | grep -q "^$device:" ; then + ip tunnel del $device + + # Test, whether removing did worked + if test_interface_status $device; then + false + fi + else + false + fi + fi + + return 0 +} + -- cgit