X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/a62f8e8a94bf56194539f7140a1215bc74309b36..HEAD:/svc/tripe-ifup.in diff --git a/svc/tripe-ifup.in b/svc/tripe-ifup.in index fc902dab..63b5b2d6 100644 --- a/svc/tripe-ifup.in +++ b/svc/tripe-ifup.in @@ -15,11 +15,27 @@ 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 + +###-------------------------------------------------------------------------- +### Error handling. + +win=t +try () { + if "$@"; then :; else + rc=$? + tripectl warn tripe-ifup command-failed rc=$rc "$*" + win=nil + fi +} + ###-------------------------------------------------------------------------- ### Collect arguments. @@ -30,11 +46,16 @@ fi peer=$1 ifname=$2 family=$3; shift 3 ## Parse the address family. +case "$family" in + INET) ipsz=20 ;; + INET6) ipsz=40 ;; + *) echo >&2 "$0: unknown address family $family"; exit 1 ;; +esac case "$family,$#" in - INET,1) addr=$1 port=4070 ;; - INET,2) addr=$1 port=$2 ;; - INET,*) echo >&2 "$0: bad INET address"; exit 1 ;; - *) echo >&2 "$0: unknown address family $family"; exit 1 ;; + INET,1 | INET6,1) addr=$1 port=4070 ;; + INET,2 | INET6,2) addr=$1 port=$2 ;; + INET,* | INET6,*) echo >&2 "$0: bad $family address"; exit 1 ;; + *) echo >&2 "$0: unknown address family $family"; exit 1 ;; esac ###-------------------------------------------------------------------------- @@ -42,37 +63,129 @@ esac case "${P_IFNAME+set}" in set) - ip link set "$ifname" name "$P_IFNAME" + try ip link set "$ifname" name "$P_IFNAME" ifname=$P_IFNAME $tripectl setifname "$peer" "$ifname" ;; esac ###-------------------------------------------------------------------------- -### Configure the point-to-point link. +### Configure the link. + +## 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) + try ip addr add "$1" peer "$r4addr" dev "$ifname" + haveaddr4=t + shift + ;; +esac +for a in "$@"; do + try ip addr add "$a" 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]*) + + ## If we're configured to set IPv6 addresses then we should ensure that + ## they're going to work, even if the default setting for new interfaces + ## is to disable IPv6. + try sysctl -q net.ipv6.conf."$ifname".disable_ipv6=0 + + ## Now add the source and destination addresses. + for a in "$@"; do + try ip addr add "$a" dev "$ifname" + haveaddr6=t + done + ;; +esac + +###-------------------------------------------------------------------------- +### Bring the interface up. -ifup=no -case "${P_LADDR+set},${P_RADDR+set}" in - set,set) +case $haveaddr4,$haveaddr6 in + nil,nil) + ;; + *) case "${P_MTU+set}" in - set) mtu=$P_MTU;; + set) + mtu=$P_MTU;; *) pathmtu=$(pathmtu "$addr") - mtu=$(expr "$pathmtu" - 33 - $A_CIPHER_BLKSZ - $A_MAC_TAGSZ) + mtu=$(( $pathmtu - $ipsz - 9 - $A_BULK_OVERHEAD )) ;; esac - ifconfig "$ifname" "$P_LADDR" pointopoint "$P_RADDR" up mtu "$mtu" - ifup=yes + try ip link set dev "$ifname" up mtu "$mtu" + ;; +esac + +###-------------------------------------------------------------------------- +### Set the peer IPv6 address if any. + +## IPv6 point-to-point links seem broken in Linux. Attach the local and +## remote addresses by hand. +set -- $l6addr +case $have6,$#,${r6addr+set} in + t,[1-9]*,set) + try ip route add $r6addr proto static dev "$ifname" ;; 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 + try ip route add $p proto static via "$r4addr" + done + ;; +esac + +## Add the v6 routes. +set -- $route6 +case $haveaddr6,$# in + t,[1-9]*) + for p in "$@"; do + try ip route add $p proto static via "${r6addr%/*}" done ;; esac @@ -89,6 +202,9 @@ esac ###-------------------------------------------------------------------------- ### Issue a notification that we've won. -$tripectl notify tripe-ifup configured "$peer" +case $win in + t) $tripectl notify tripe-ifup configured "$peer" ;; + nil) $tripectl notify tripe-ifup configured "$peer" failed ;; +esac ###----- That's all, folks --------------------------------------------------