Commit | Line | Data |
---|---|---|
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 | ||
16 | set -e | |
17 | ||
90b20d79 | 18 | ## Import compile-time configuration. |
a62f8e8a MW |
19 | : ${bindir=@bindir@} |
20 | : ${tripectl=$bindir/tripectl} | |
21 | PATH=/usr/bin:/usr/sbin:/bin:/sbin:$bindir | |
22 | export PATH TRIPEDIR | |
23 | ||
90b20d79 MW |
24 | ## Determine whether we have IPv6 support. |
25 | if [ -d /proc/sys/net/ipv6 ]; then have6=t; else have6=nil; fi | |
26 | ||
a62f8e8a | 27 | ###-------------------------------------------------------------------------- |
49bfe6a2 MW |
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 | ###-------------------------------------------------------------------------- | |
a62f8e8a MW |
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. | |
47828bd9 MW |
49 | case "$family" in |
50 | INET) ipsz=20 ;; | |
51 | INET6) ipsz=40 ;; | |
52 | *) echo >&2 "$0: unknown address family $family"; exit 1 ;; | |
53 | esac | |
a62f8e8a | 54 | case "$family,$#" in |
47828bd9 MW |
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 ;; | |
a62f8e8a MW |
59 | esac |
60 | ||
61 | ###-------------------------------------------------------------------------- | |
62 | ### Set the interface name. | |
63 | ||
64 | case "${P_IFNAME+set}" in | |
65 | set) | |
49bfe6a2 | 66 | try ip link set "$ifname" name "$P_IFNAME" |
a62f8e8a MW |
67 | ifname=$P_IFNAME |
68 | $tripectl setifname "$peer" "$ifname" | |
69 | ;; | |
70 | esac | |
71 | ||
72 | ###-------------------------------------------------------------------------- | |
baa631c5 | 73 | ### Configure the link. |
a62f8e8a | 74 | |
90b20d79 MW |
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) | |
49bfe6a2 | 100 | try ip addr add "$1" peer "$r4addr" dev "$ifname" |
90b20d79 MW |
101 | haveaddr4=t |
102 | shift | |
103 | ;; | |
104 | esac | |
105 | for a in "$@"; do | |
49bfe6a2 | 106 | try ip addr add "$a" dev "$ifname" |
90b20d79 MW |
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]*) | |
152a2182 MW |
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. | |
90b20d79 | 123 | for a in "$@"; do |
49bfe6a2 | 124 | try ip addr add "$a" dev "$ifname" |
90b20d79 MW |
125 | haveaddr6=t |
126 | done | |
a62f8e8a MW |
127 | ;; |
128 | esac | |
129 | ||
130 | ###-------------------------------------------------------------------------- | |
f5d185e4 MW |
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") | |
47828bd9 | 142 | mtu=$(( $pathmtu - $ipsz - 9 - $A_BULK_OVERHEAD )) |
f5d185e4 MW |
143 | ;; |
144 | esac | |
49bfe6a2 | 145 | try ip link set dev "$ifname" up mtu "$mtu" |
f5d185e4 MW |
146 | ;; |
147 | esac | |
148 | ||
149 | ###-------------------------------------------------------------------------- | |
0fc1588c MW |
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 | ###-------------------------------------------------------------------------- | |
a62f8e8a MW |
162 | ### Set up routing. |
163 | ||
90b20d79 MW |
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 | |
49bfe6a2 | 178 | try ip route add $p proto static via "$r4addr" |
90b20d79 MW |
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 | |
49bfe6a2 | 188 | try ip route add $p proto static via "${r6addr%/*}" |
a62f8e8a MW |
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 | ||
49bfe6a2 MW |
205 | case $win in |
206 | t) $tripectl notify tripe-ifup configured "$peer" ;; | |
207 | nil) $tripectl notify tripe-ifup configured "$peer" failed ;; | |
208 | esac | |
a62f8e8a MW |
209 | |
210 | ###----- That's all, folks -------------------------------------------------- |