svc/tripe-ifup.in: Support IPv6 address configuration.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 19 Mar 2012 22:15:41 +0000 (22:15 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 19 Mar 2012 22:17:17 +0000 (22:17 +0000)
This switches the script to use the ip(8) utility for all of its
configuration.

debian/control
svc/tripe-ifup.8.in
svc/tripe-ifup.in

index aaa36c1..2c4d258 100644 (file)
@@ -100,7 +100,8 @@ Description: Trivial IP Encryption: a simple virtual private network
 
 Package: tripe-peer-services
 Architecture: all
-Depends: python (>= 2.4), python-mlib, tripe, python-cdb, python-tripe, pathmtu
+Depends: python (>= 2.4), python-mlib, tripe, python-cdb, python-tripe,
+       pathmtu, iproute
 Description: Trivial IP Encryption: a simple virtual private network
  TrIPE is a simple VPN protocol.  It uses cryptography to ensure secrecy
  and authenticity of packets it sends and receives.
index 0fe89d8..440c284 100644 (file)
@@ -101,36 +101,44 @@ a
 command is issued to keep the server informed.  Further configuration is
 performed using the new interface name.
 .hP 2.
-The point-to-point interface is configured.  If
+Configure the interface addresses.  If
 .I laddr
-and
+is set, it should be a space-separated list of IPv4 and IPv6 addresses:
+there may be any number of either.
+If
 .I raddr
-are set, then the interface is configured to be a point-to-point link
-from
-.I laddr
-to
-.IR raddr .
-Both are expected to be network addresses in dotted-quad form.  The
-interface MTU is configured based on the path MTU to the peer's external
-address and the cryptographic algorithms in use by the
-.BR tripe (8)
-server; this can be overridden by setting the
-.I mtu
-key.
+is set, it should be an IPv4 and/or an IPv6 address, separated by space:
+these are the addresses to configure as the remote end point of the
+point-to-point link.  (Further remote addresses can be configured as
+host routes: see below.)  IPv4 addresses are expected to be in
+dotted-quad form; IPv6 addresses should be in RFC4291 hex-and-colons
+form.
 .hP 3.
-Establish routes.  If the interface was configured, and
+Establish routes.  If addresses were configured, and
 .I nets
 is set, then
 .I nets
 is split into space-separated networks.  For each network, of the form
 .IB address / mask \fR,
 a route is configured to the given network, via the remote address of
-the link, over the tunnel interface.
+the link, over the tunnel interface.  The
+.IR address es
+may be IPv4 or IPv6 addresses.  If the interface has only an IPv4
+address then IPv6 routes will be ignored, and
+.IR "vice versa" .
 .hP 4.
+Configure the interface MTU and bring it up.  The
+interface MTU is configured based on the path MTU to the peer's external
+address and the cryptographic algorithms in use by the
+.BR tripe (8)
+server; this can be overridden by setting the
+.I mtu
+key.
+.hP 5.
 Invoke user hook.  If
 .I ifupextra
 is set, it is interpreted as a Bourne shell command and evaluated.
-.hP 5.
+.hP 6.
 Notify services.  A notification
 .RS
 .IP
index fc902da..8ca0c99 100644 (file)
 
 set -e
 
+## Import compile-time configuration.
 : ${bindir=@bindir@}
 : ${tripectl=$bindir/tripectl}
 PATH=/usr/bin:/usr/sbin:/bin:/sbin:$bindir
 export PATH TRIPEDIR
 
+## Determine whether we have IPv6 support.
+if [ -d /proc/sys/net/ipv6 ]; then have6=t; else have6=nil; fi
+
 ###--------------------------------------------------------------------------
 ### Collect arguments.
 
@@ -51,33 +55,109 @@ esac
 ###--------------------------------------------------------------------------
 ### Configure the point-to-point link.
 
-ifup=no
-case "${P_LADDR+set},${P_RADDR+set}" in
-  set,set)
-    case "${P_MTU+set}" in
-      set) mtu=$P_MTU;;
-      *)
-       pathmtu=$(pathmtu "$addr")
-       mtu=$(expr "$pathmtu" - 33 - $A_CIPHER_BLKSZ - $A_MAC_TAGSZ)
-       ;;
+## Split local addresses into v4 and v6 lists.
+unset l4addr l6addr
+for a in $P_LADDR; do
+  case "$a" in
+    *:*) l6addr=${l6addr+$l6addr }$a ;;
+    *)   l4addr=${l4addr+$l4addr }$a ;;
+  esac
+done
+
+## Determine the remote v4 and v6 addresses.  We only allow one remote
+## address for each: others can be added as routes.
+unset r4addr r6addr
+for a in $P_RADDR; do
+  case "$a" in
+    *:*) r6addr=$a ;;
+    *)   r4addr=$a ;;
+  esac
+done
+
+## Configure the first v4 address as point-to-point; add the others as plain
+## addresses.
+haveaddr4=nil
+set -- $l4addr
+case $#,${r4addr+set} in
+  [1-9]*,set)
+    ip addr add "$1" peer "$r4addr" dev "$ifname"
+    haveaddr4=t
+    shift
+    ;;
+esac
+for a in "$@"; do
+  ip addr add "$a/32" dev "$ifname"
+  haveaddr4=t
+done
+
+## IPv6 point-to-point links seem broken in Linux.  Attach the local and
+## remote addresses by hand.
+haveaddr6=nil
+set -- $l6addr
+case $have6,$# in
+  t,[1-9]*)
+    for a in "$@"; do
+      ip addr add "$a/128" dev "$ifname"
+      haveaddr6=t
+    done
+    case ${r6addr+set} in
+      set) ip route add $r6addr/128 dev "$ifname" ;;
     esac
-    ifconfig "$ifname" "$P_LADDR" pointopoint "$P_RADDR" up mtu "$mtu"
-    ifup=yes
     ;;
 esac
 
 ###--------------------------------------------------------------------------
 ### Set up routing.
 
-case "$ifup,${P_NETS+set}" in
-  yes,set)
-    for net in $P_NETS; do
-      route add -net $net gw "$P_RADDR" dev "$ifname" metric 2
+## Split the routes into v4 and v6 lists.
+unset route4 route6
+for p in $P_NETS; do
+  case "$p" in
+    *:*) route6=${route6+$route6 }$p ;;
+    *)   route4=${route4+$route4 }$p ;;
+  esac
+done
+
+## Add the v4 routes.
+set -- $route4
+case $haveaddr4,$# in
+  t,[1-9]*)
+    for p in "$@"; do
+      ip route add $p via "$r4addr"
+    done
+    ;;
+esac
+
+## Add the v6 routes.
+set -- $route6
+case $haveaddr6,$# in
+  t,[1-9]*)
+    for p in "$@"; do
+      ip route add $p via "$r6addr"
     done
     ;;
 esac
 
 ###--------------------------------------------------------------------------
+### Bring the interface up.
+
+case $haveaddr4,$haveaddr6 in
+  nil,nil)
+    ;;
+  *)
+    case "${P_MTU+set}" in
+      set)
+       mtu=$P_MTU;;
+      *)
+       pathmtu=$(pathmtu "$addr")
+       mtu=$(expr "$pathmtu" - 33 - $A_CIPHER_BLKSZ - $A_MAC_TAGSZ)
+       ;;
+    esac
+    ip link set dev "$ifname" up mtu "$mtu"
+    ;;
+esac
+
+###--------------------------------------------------------------------------
 ### Maybe invoke a follow-on script.
 
 case "${P_IFUPEXTRA+set}" in