From 90b20d79a9ec5b8a44bb92c8abdb21948aeb062c Mon Sep 17 00:00:00 2001 Message-Id: <90b20d79a9ec5b8a44bb92c8abdb21948aeb062c.1713252941.git.mdw@distorted.org.uk> From: Mark Wooding Date: Mon, 19 Mar 2012 22:15:41 +0000 Subject: [PATCH] svc/tripe-ifup.in: Support IPv6 address configuration. Organization: Straylight/Edgeware From: Mark Wooding This switches the script to use the ip(8) utility for all of its configuration. --- debian/control | 3 +- svc/tripe-ifup.8.in | 42 ++++++++++------- svc/tripe-ifup.in | 110 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 122 insertions(+), 33 deletions(-) diff --git a/debian/control b/debian/control index aaa36c18..2c4d2581 100644 --- a/debian/control +++ b/debian/control @@ -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. diff --git a/svc/tripe-ifup.8.in b/svc/tripe-ifup.8.in index 0fe89d82..440c2842 100644 --- a/svc/tripe-ifup.8.in +++ b/svc/tripe-ifup.8.in @@ -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 diff --git a/svc/tripe-ifup.in b/svc/tripe-ifup.in index fc902dab..8ca0c99c 100644 --- a/svc/tripe-ifup.in +++ b/svc/tripe-ifup.in @@ -15,11 +15,15 @@ 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,32 +55,108 @@ 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. -- [mdw]