#! /bin/sh ### ### TrIPE interface initialization script ### suitable for Linux; other operating systems probably want something ### similar ###----- Licensing notica --------------------------------------------------- ### ### Redistribution, modification and use of this file is permitted without ### limitation. ### ### This file is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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. ## Collect the simple arguments. if [ $# -lt 3 ]; then echo >&2 "usage: $0 PEER IFNAME ADDR..."; exit 1 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 | 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 ###-------------------------------------------------------------------------- ### Set the interface name. case "${P_IFNAME+set}" in set) try ip link set "$ifname" name "$P_IFNAME" ifname=$P_IFNAME $tripectl setifname "$peer" "$ifname" ;; esac ###-------------------------------------------------------------------------- ### 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. case $haveaddr4,$haveaddr6 in nil,nil) ;; *) case "${P_MTU+set}" in set) mtu=$P_MTU;; *) pathmtu=$(pathmtu "$addr") mtu=$(( $pathmtu - $ipsz - 9 - $A_BULK_OVERHEAD )) ;; esac 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. ## 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 ###-------------------------------------------------------------------------- ### Maybe invoke a follow-on script. case "${P_IFUPEXTRA+set}" in set) eval "$P_IFUPEXTRA" ;; esac ###-------------------------------------------------------------------------- ### Issue a notification that we've won. case $win in t) $tripectl notify tripe-ifup configured "$peer" ;; nil) $tripectl notify tripe-ifup configured "$peer" failed ;; esac ###----- That's all, folks --------------------------------------------------