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