#!/bin/sh # # network-functions-ipv6 # # Taken from: # (P) & (C) 1997-2001 by Peter Bieringer # # Version: 2001-02-22 # # Filter tags (for stripping, empty lines following if all is stripped) # Return values # 0 = ok # 1 = error occurs # 2 = not enabled, i.e. no IPv6 kernel support or switched off by configuration ##### Test for IPv6 capabilites 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" return 2 fi fi return 0 } ##### Control IPv6 forwarding # Display usage function forwarding_ipv6_usage() { echo $"Usage: $0 yes|no [device]" } # 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 if [ -z $fw_control ]; then echo $"Missing parameter 'forwarding control'" forwarding_ipv6_usage 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 return 1 fi # Device "lo" need no IPv6 configuration if [ "$fw_device" = "lo" ]; then return 0; fi # Run IPv6 test test_ipv6 || return if [ "$fw_control" = "yes" -o "$fw_control" = "on" ]; then status=1 else 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 fi # Per device control if [ ! -z $fw_device ]; then sysctl -w net.ipv6.conf.$fw_device.forwarding=$status >/dev/null 2>&1 fi } ##### 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 # $3: Interface (optional) function ifup_ipv6_route() { networkipv6=$1 gatewayipv6=$2 device=$3 # maybe empty if [ -z $networkipv6 ]; then echo $"Missing parameter 'IPv6-network'" ifupdown_ipv6_route_usage return 1 fi if [ -z $gatewayipv6 ]; then echo $"Missing parameter 'IPv6-gateway'" ifupdown_ipv6_route_usage return 1 fi # Device "lo" need no IPv6 configuration if [ "$device" = "lo" ]; then return 0; fi # Run IPv6 test test_ipv6 || return if [ -z $device ]; then route -A inet6 add $networkipv6 gw $gatewayipv6 else route -A inet6 add $networkipv6 gw $gatewayipv6 dev $device fi } # Delete static IPv6 route # $1: IPv6 network to route # $2: IPv6 gateway over which $1 should be routed # $3: Interface (optional) function ifdown_ipv6_route() { networkipv6=$1 gatewayipv6=$2 device=$3 # maybe empty if [ -z $networkipv6 ]; then echo $"Missing parameter 'IPv6-network'" ifup_ipv6_route_usage return 1 fi if [ -z $gatewayipv6 ]; then echo $"Missing parameter 'IPv6-gateway'" ifup_ipv6_route_usage return 1 fi # Device "lo" need no IPv6 configuration if [ "$device" = "lo" ]; then return 0; fi # Run IPv6 test test_ipv6 || return if [ -z $device ]; then route -A inet6 del $networkipv6 gw $gatewayipv6 else route -A inet6 del $networkipv6 gw $gatewayipv6 dev $device fi } ##### automatic tunneling configuration ## Configure automatic tunneling up function ifup_ipv6_autotunnel() { # Run IPv6 test test_ipv6 || return # enable IPv6-over-IPv4 tunnels if LANG=C ifconfig sit0 | grep -q "UP "; then # already up, do nothing true else # basic tunnel device to up ifconfig sit0 up # Switch on forwarding forwarding_ipv6 on sit0 fi } ## Configure automatic tunneling down function ifdown_ipv6_autotunnel() { # Run IPv6 test test_ipv6 || return # disable IPv6-over-IPv4 tunnels (if a tunnel is no longer up) if route -A inet6 -n | grep sit0 | grep -v -q "^::"; then # existing routes, do nothing true else # basic tunnel device to down # Switch off forwarding forwarding_ipv6 off sit0 ifconfig sit0 down fi } ##### static tunneling configuration function ifupdown_ipv6_tunnel_usage() { echo $"Usage: $0 interfacename IPv4-tunneladdress IPv6-route" } ## 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 if [ -z $device ]; then echo $"Missing parameter 'device'" ifupdown_ipv6_tunnel_usage return 1 fi if [ -z $addressipv4tunnel ]; then echo $"Missing parameter 'IPv4-tunneladdress'" ifupdown_ipv6_tunnel_usage return 1 fi if [ -z $routeipv6 ]; then echo $"Missing parameter 'IPv6-route'" ifupdown_ipv6_tunnel_usage return 1 fi # Run IPv6 test test_ipv6 || return # enable general IPv6-over-IPv4 tunneling ifup_ipv6_autotunnel # Set up a tunnel route -A inet6 add $routeipv6 gw ::$addressipv4tunnel dev sit0 } ## Configure static tunnels down # $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 if [ -z $device ]; then echo $"Missing parameter 'device'" ifupdown_ipv6_tunnel_usage return 1 fi if [ -z $addressipv4tunnel ]; then echo $"Missing parameter 'IPv4-tunneladdress'" ifupdown_ipv6_tunnel_usage return 1 fi if [ -z $routeipv6 ]; then echo $"Missing parameter 'IPv6-route'" ifupdown_ipv6_tunnel_usage return 1 fi # Run IPv6 test test_ipv6 || return # Set up a tunnel route -A inet6 del $routeipv6 gw ::$addressipv4tunnel dev sit0 # disable IPv6-over-IPv4 tunneling (if no longer a tunnel is up) ifdown_ipv6_autotunnel } ##### 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 if [ -z $device ]; then echo $"Missing parameter 'device'" 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'" ifupdown_ipv6_usage return 1 fi # Test status of interface if LANG=C ifconfig $device | grep -q "UP "; then # Interface is 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 }'`" # 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 fi # Run IPv6 test test_ipv6 || return # Only add, if address do not already exist address_configured="`LANG=C ifconfig $device | grep "inet6 addr:" | grep "$address" | awk '{ print $3 }'`" address_configured_type="`LANG=C ifconfig $device | grep "inet6 addr:" | grep "$address" | awk '{ print $4 }'`" if [ "$address_configured" = "$address" ]; then true else ifconfig $device add $address || return 2 fi } ## Remove all IPv6 routes and addresses for given interface # cleanup to prevent kernel crashes # $1: Interface function ifdown_ipv6_real_all() { idall_device=$1 if [ -z $idall_device ]; then echo $"Missing parameter 'idall_device'" echo $"Usage: ifdown_ipv6_real_all interfacename" return 1 fi # Get all IPv6 routes through given interface and remove them route -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 fi done # Get all IPv6 addresses assigned to given interface and remove them LANG=C ifconfig $idall_device | grep "inet6 addr:" | awk '{ print $3 }' | while read ipv6addr args; do ifdown_ipv6_real $idall_device $ipv6addr done } ## Remove an IPv6 address on given interface # $1: Interface # $2: IPv6 address function ifdown_ipv6_real() { device=$1 address=$2 if [ -z $device ]; then echo $"Missing parameter 'device'" 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'" 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 }'`" # 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 fi # Run IPv6 test test_ipv6 || return # Only remove, if address exists and is not link-local (prevents from kernel crashing) address_configured="`LANG=C ifconfig $device | grep "inet6 addr:" | grep "$address" | awk '{ print $3 }'`" address_configured_type="`LANG=C ifconfig $device | grep "inet6 addr:" | grep "$address" | awk '{ print $4 }'`" if [ ! -z "$address_configured" ]; then if [ "$address_configured_type" = "Scope:Link" ]; then true else ifconfig $device del $address || return 2 fi else true fi }