chiark / gitweb /
Merge branch '1.0.0pre19.x'
[tripe] / svc / tripe-ifup.in
1 #! /bin/sh
2 ###
3 ### TrIPE interface initialization script
4 ###   suitable for Linux; other operating systems probably want something
5 ###   similar
6
7 ###----- Licensing notica ---------------------------------------------------
8 ###
9 ### Redistribution, modification and use of this file is permitted without
10 ### limitation.
11 ###
12 ### This file is distributed in the hope that it will be useful,
13 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 set -e
17
18 ## Import compile-time configuration.
19 : ${bindir=@bindir@}
20 : ${tripectl=$bindir/tripectl}
21 PATH=/usr/bin:/usr/sbin:/bin:/sbin:$bindir
22 export PATH TRIPEDIR
23
24 ## Determine whether we have IPv6 support.
25 if [ -d /proc/sys/net/ipv6 ]; then have6=t; else have6=nil; fi
26
27 ###--------------------------------------------------------------------------
28 ### Error handling.
29
30 win=t
31 try () {
32   if "$@"; then :; else
33     rc=$?
34     tripectl warn tripe-ifup command-failed rc=$rc "$*"
35     win=nil
36   fi
37 }
38
39 ###--------------------------------------------------------------------------
40 ### Collect arguments.
41
42 ## Collect the simple arguments.
43 if [ $# -lt 3 ]; then
44   echo >&2 "usage: $0 PEER IFNAME ADDR..."; exit 1
45 fi
46 peer=$1 ifname=$2 family=$3; shift 3
47
48 ## Parse the address family.
49 case "$family" in
50   INET) ipsz=20 ;;
51   INET6) ipsz=40 ;;
52   *) echo >&2 "$0: unknown address family $family"; exit 1 ;;
53 esac
54 case "$family,$#" in
55   INET,1 | INET6,1) addr=$1 port=4070 ;;
56   INET,2 | INET6,2) addr=$1 port=$2 ;;
57   INET,* | INET6,*) echo >&2 "$0: bad $family address"; exit 1 ;;
58   *) echo >&2 "$0: unknown address family $family"; exit 1 ;;
59 esac
60
61 ###--------------------------------------------------------------------------
62 ### Set the interface name.
63
64 case "${P_IFNAME+set}" in
65   set)
66     try ip link set "$ifname" name "$P_IFNAME"
67     ifname=$P_IFNAME
68     $tripectl setifname "$peer" "$ifname"
69     ;;
70 esac
71
72 ###--------------------------------------------------------------------------
73 ### Configure the link.
74
75 ## Split local addresses into v4 and v6 lists.
76 unset l4addr l6addr
77 for a in $P_LADDR; do
78   case "$a" in
79     *:*) l6addr=${l6addr+$l6addr }$a ;;
80     *)   l4addr=${l4addr+$l4addr }$a ;;
81   esac
82 done
83
84 ## Determine the remote v4 and v6 addresses.  We only allow one remote
85 ## address for each: others can be added as routes.
86 unset r4addr r6addr
87 for a in $P_RADDR; do
88   case "$a" in
89     *:*) r6addr=$a ;;
90     *)   r4addr=$a ;;
91   esac
92 done
93
94 ## Configure the first v4 address as point-to-point; add the others as plain
95 ## addresses.
96 haveaddr4=nil
97 set -- $l4addr
98 case $#,${r4addr+set} in
99   [1-9]*,set)
100     try ip addr add "$1" peer "$r4addr" dev "$ifname"
101     haveaddr4=t
102     shift
103     ;;
104 esac
105 for a in "$@"; do
106   try ip addr add "$a" dev "$ifname"
107   haveaddr4=t
108 done
109
110 ## IPv6 point-to-point links seem broken in Linux.  Attach the local and
111 ## remote addresses by hand.
112 haveaddr6=nil
113 set -- $l6addr
114 case $have6,$# in
115   t,[1-9]*)
116
117     ## If we're configured to set IPv6 addresses then we should ensure that
118     ## they're going to work, even if the default setting for new interfaces
119     ## is to disable IPv6.
120     try sysctl -q net.ipv6.conf."$ifname".disable_ipv6=0
121
122     ## Now add the source and destination addresses.
123     for a in "$@"; do
124       try ip addr add "$a" dev "$ifname"
125       haveaddr6=t
126     done
127     ;;
128 esac
129
130 ###--------------------------------------------------------------------------
131 ### Bring the interface up.
132
133 case $haveaddr4,$haveaddr6 in
134   nil,nil)
135     ;;
136   *)
137     case "${P_MTU+set}" in
138       set)
139         mtu=$P_MTU;;
140       *)
141         pathmtu=$(pathmtu "$addr")
142         mtu=$(( $pathmtu - $ipsz - 9 - $A_BULK_OVERHEAD ))
143         ;;
144     esac
145     try ip link set dev "$ifname" up mtu "$mtu"
146     ;;
147 esac
148
149 ###--------------------------------------------------------------------------
150 ### Set the peer IPv6 address if any.
151
152 ## IPv6 point-to-point links seem broken in Linux.  Attach the local and
153 ## remote addresses by hand.
154 set -- $l6addr
155 case $have6,$#,${r6addr+set} in
156   t,[1-9]*,set)
157     try ip route add $r6addr proto static dev "$ifname"
158     ;;
159 esac
160
161 ###--------------------------------------------------------------------------
162 ### Set up routing.
163
164 ## Split the routes into v4 and v6 lists.
165 unset route4 route6
166 for p in $P_NETS; do
167   case "$p" in
168     *:*) route6=${route6+$route6 }$p ;;
169     *)   route4=${route4+$route4 }$p ;;
170   esac
171 done
172
173 ## Add the v4 routes.
174 set -- $route4
175 case $haveaddr4,$# in
176   t,[1-9]*)
177     for p in "$@"; do
178       try ip route add $p proto static via "$r4addr"
179     done
180     ;;
181 esac
182
183 ## Add the v6 routes.
184 set -- $route6
185 case $haveaddr6,$# in
186   t,[1-9]*)
187     for p in "$@"; do
188       try ip route add $p proto static via "${r6addr%/*}"
189     done
190     ;;
191 esac
192
193 ###--------------------------------------------------------------------------
194 ### Maybe invoke a follow-on script.
195
196 case "${P_IFUPEXTRA+set}" in
197   set)
198     eval "$P_IFUPEXTRA"
199     ;;
200 esac
201
202 ###--------------------------------------------------------------------------
203 ### Issue a notification that we've won.
204
205 case $win in
206   t) $tripectl notify tripe-ifup configured "$peer" ;;
207   nil) $tripectl notify tripe-ifup configured "$peer" failed ;;
208 esac
209
210 ###----- That's all, folks --------------------------------------------------