]> git.ipfire.org Git - people/ms/network.git/blame - src/functions/functions.ip-tunnel
ip-tunnel: Set TTL to 255 by default
[people/ms/network.git] / src / functions / functions.ip-tunnel
CommitLineData
cccb3a4b
MT
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
9390b61b 5# Copyright (C) 2012-2013 IPFire Network Development Team #
cccb3a4b
MT
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program 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. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
a1da77dd 22IP_TUNNEL_MODES="gre gretap sit vti"
cccb3a4b 23
85de251d
MT
24ip_tunnel_protocol_to_name() {
25 local protocol="${1}"
26
27 case "${protocol}" in
28 gre)
29 print "Generic Routing Encapsulation"
30 ;;
31 sit)
32 print "Simple Internet Transition"
33 ;;
34 vti)
35 print "Virtual Tunnel Interface"
36 ;;
37 *)
38 print "${protocol}"
39 ;;
40 esac
41}
42
376629dc
JS
43# This function converts our modes into the type
44# the iproute2 tool uses
45ip_tunnel_convert_mode_to_iproute2_mode() {
46 local mode=${1}
47 local protocol=${2}
48
49 if ! isset mode || ! isset protocol; then
50 log ERROR "Did not get mode and/or protocol"
51 return ${EXIT_ERROR}
52 fi
53
54 if [[ "${protocol}" = "ipv4" ]]; then
55 # When we use IPv4 we can use our modes
56 echo "${mode}"
57 fi
58
59 if [[ "${protocol}" = "ipv6" ]]; then
60 # When we use IPv6 we have to convert
61 case "${mode}" in
62 "vti")
63 echo "vti6"
64 ;;
65 "gre")
66 echo "ip6gre"
a1da77dd
MT
67 ;;
68 "gretap")
69 echo "ip6gretap"
70 ;;
376629dc
JS
71 esac
72 fi
73}
74
1c6a4e30 75ip_tunnel_add() {
a1da77dd 76 local device="${1}"
cccb3a4b
MT
77 shift
78
1a02da59 79 local mode
ae2c5b2b 80 local ttl=255
cccb3a4b 81
a1da77dd 82 local address
cccb3a4b
MT
83 local remote_address
84 local local_address
85
1a02da59
MT
86 local ikey
87 local okey
88
cccb3a4b
MT
89 while [ $# -gt 0 ]; do
90 case "${1}" in
a1da77dd
MT
91 --address=*)
92 address="$(cli_get_val "${1}")"
93
94 # Validate input
95 if ! isset address || ! mac_is_valid "${address}"; then
96 error "Invalid MAC address: ${address}"
97 return ${EXIT_ERROR}
98 fi
99 ;;
cccb3a4b 100 --mode=*)
2212045f 101 mode="$(cli_get_val "${1}")"
cccb3a4b
MT
102 ;;
103 --ttl=*)
2212045f 104 ttl="$(cli_get_val "${1}")"
cccb3a4b 105 ;;
cccb3a4b 106 --remote-address=*)
2212045f 107 remote_address="$(cli_get_val "${1}")"
cccb3a4b
MT
108 ;;
109 --local-address=*)
2212045f 110 local_address="$(cli_get_val "${1}")"
cccb3a4b 111 ;;
1a02da59
MT
112
113 # Keys for VTI
114 --ikey=*)
2212045f 115 ikey="$(cli_get_val "${1}")"
1a02da59
MT
116 ;;
117 --okey=*)
2212045f 118 okey="$(cli_get_val "${1}")"
1a02da59 119 ;;
cccb3a4b
MT
120 esac
121 shift
122 done
123
1a02da59
MT
124 if ! isset mode; then
125 error "--mode= is not set. Must be one of ${IP_TUNNEL_MODES}"
126 return ${EXIT_ERROR}
127 fi
128
129 if ! isoneof mode ${IP_TUNNEL_MODES}; then
130 error "Invalid mode: ${mode}"
131 return ${EXIT_ERROR}
132 fi
133
5bbd1fab 134 # We cannot mix IPv6 and IPv4
2a588cab
MT
135 if isset local_address && ! ip_protocol_match "${remote_address}" "${local_address}"; then
136 log ERROR "Local and remote address are not of the same IP protocol"
5bbd1fab
JS
137 return ${EXIT_ERROR}
138 fi
139
1a02da59
MT
140 # ikey and okey must be set for VTI devices
141 if [ "${mode}" = "vti" ] && (! isset ikey || ! isset okey); then
142 error "--ikey= and --okey= must be set for VTI device"
143 return ${EXIT_ERROR}
144 fi
cccb3a4b 145
a1da77dd
MT
146 # Custom checks for certain modes
147 case "${mode}" in
148 gretap)
149 # Generate a random MAC address if none was passed
150 if ! isset address; then
151 address="$(mac_generate)"
152 fi
153 ;;
154 esac
155
cccb3a4b 156 # If TTL is set, make sure it is an integer.
1a02da59
MT
157 if isset ttl && ! isinteger ttl; then
158 error "TTL must be an integer: ${ttl}"
159 return ${EXIT_ERROR}
160 fi
cccb3a4b 161
a1da77dd
MT
162 # Determine the mode based on the IP protocol
163 local remote_address_protocol="$(ip_detect_protocol "${remote_address}")"
164 mode=$(ip_tunnel_convert_mode_to_iproute2_mode "${mode}" "${remote_address_protocol}")
165
166 local cmd_args=( name "${device}" )
167
168 if isset address; then
169 cmd_args=( "${cmd_args[@]}" "address" "${address}" )
170 fi
171
172 # Mode
173 cmd_args=( "${cmd_args[@]}" "type" "${mode}" )
cccb3a4b
MT
174
175 # Apply TTL if a value has been set.
176 if isset ttl; then
a1da77dd 177 cmd_args=( "${cmd_args[@]}" "ttl" "${ttl}" )
cccb3a4b
MT
178 fi
179
eec68f19
MT
180 # Apply local address if a value has been set.
181 if isset local_address; then
a1da77dd 182 cmd_args=( "${cmd_args[@]}" "local" "${local_address}" )
eec68f19
MT
183 fi
184
9390b61b
SS
185 # Apply remote address if a value has been set.
186 if isset remote_address; then
a1da77dd 187 cmd_args=( "${cmd_args[@]}" "remote" "${remote_address}" )
9390b61b
SS
188 fi
189
1a02da59
MT
190 # Add ikey and okey for VTI devices
191 if [ "${mode}" = "vti" ]; then
a1da77dd 192 cmd_args=( "${cmd_args[@]}" "ikey" "${ikey}" "okey" "${okey}" )
1a02da59
MT
193 fi
194
cccb3a4b
MT
195 log DEBUG "Creating tunnel device '${device}' (mode=${mode})..."
196
197 # Create the device.
a1da77dd 198 if ! cmd ip link add "${cmd_args[@]}"; then
1a02da59
MT
199 error "Could not create tunnel device ${device}"
200 return ${EXIT_ERROR}
201 fi
ea1857e3
MT
202
203 # Disable policy lookups for VTI devices
204 if [ "${mode}" = "vti" ]; then
205 sysctl_set "net.ipv4.conf.${device}.disable_policy" "1"
206 fi
207
208 return ${EXIT_OK}
cccb3a4b
MT
209}
210
1c6a4e30 211ip_tunnel_del() {
21e8d1aa 212 device_delete "$@"
cccb3a4b 213}
82fac748 214
4f5f487a
MT
215ip_tunnel_change() {
216 local device="${1}"
217 shift
218
219 if ! device_exists "${device}"; then
220 log ERROR "No such device: ${device}"
221 return ${EXIT_ERROR}
222 fi
223
224 # Determine the device type
225 local type="$(device_tunnel_get_type ${device})"
226
227 local local
228 local remote
229
230 while [ $# -gt 0 ]; do
231 case "${1}" in
232 --local=*)
233 local="$(cli_get_val "${1}")"
234
235 if ! ip_is_valid "${local}"; then
236 error "Invalid IP address for --local: ${local}"
237 return ${EXIT_ERROR}
238 fi
239
240 if ! isoneof "type" gre gre6 vti vti6; then
241 log ERROR "Cannot change --local for devices of type ${type}"
242 return ${EXIT_ERROR}
243 fi
244 ;;
245 --remote=*)
246 remote="$(cli_get_val "${1}")"
247
248 if ! ip_is_valid "${remote}"; then
249 error "Invalid IP address for --remote: ${remote}"
250 return ${EXIT_ERROR}
251 fi
252
253 if ! isoneof "type" gre gre6 vti vti6; then
254 log ERROR "Cannot change --remote for devices of type ${type}"
255 return ${EXIT_ERROR}
256 fi
257 ;;
258 esac
259 shift
260 done
261
262 # XXX If a device is of an IP protocol and the protocol of remote and local
263 # have changed, we will need to destroy the interface and recreate it with
264 # the correct type
265
266 local cmd_args
267
268 if isset local; then
269 cmd_args="${cmd_args} local ${local}"
270 fi
271
272 if isset remote; then
273 cmd_args="${cmd_args} remote ${remote}"
274 fi
275
276 # Exit if there is nothing to do
277 if ! isset cmd_args; then
278 return ${EXIT_OK}
279 fi
280
281 # Run ip command
282 cmd ip link change dev "${device}" type "${type}" ${cmd_args}
283}