]> git.ipfire.org Git - people/stevee/network.git/blob - src/hooks/ports/ip-tunnel
3943e4cd3bea3f5aa3881e922d727411a9102bdc
[people/stevee/network.git] / src / hooks / ports / ip-tunnel
1 #!/bin/bash
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2018 IPFire Network Development Team #
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
22 . /usr/lib/network/header-port
23
24 SUPPORTED_IP_TUNNEL_MODES="gretap"
25
26 HOOK_SETTINGS="ADDRESS MARK MODE PEER LOCAL_ADDRESS"
27
28 hook_check_settings() {
29 assert isset MODE
30 assert isoneof MODE ${SUPPORTED_IP_TUNNEL_MODES}
31
32 assert isset ADDRESS
33 assert mac_is_valid "${ADDRESS}"
34
35 # Generate a random mark
36 if ! isset MARK; then
37 MARK="$(( ${RANDOM} & 0xffffffff ))"
38 fi
39 }
40
41 hook_parse_cmdline() {
42 while [ $# -gt 0 ]; do
43 case "${1}" in
44 --address=*)
45 ADDRESS="$(cli_get_val "${1}")"
46
47 if ! isset ADDRESS || ! mac_is_valid "${ADDRESS}"; then
48 error "Invalid MAC address: ${ADDRESS}"
49 return ${EXIT_ERROR}
50 fi
51 ;;
52
53 --local-address=*)
54 LOCAL_ADDRESS="$(cli_get_val "${1}")"
55 ;;
56
57 --mode=*)
58 MODE="$(cli_get_val "${1}")"
59
60 # MODE must be on the list of supported protocols
61 if ! isoneof MODE ${SUPPORTED_IP_TUNNEL_MODES}; then
62 error "Unsupported mode: ${mode}"
63 return ${EXIT_ERROR}
64 fi
65 ;;
66
67 --peer=*)
68 PEER="$(cli_get_val "${1}")"
69 ;;
70
71 *)
72 error "Unknown option: ${1}"
73 return ${EXIT_ERROR}
74 ;;
75 esac
76 shift
77 done
78
79 # Generate a random MAC address if none is set
80 if ! isset ADDRESS; then
81 ADDRESS="$(mac_generate)"
82 fi
83
84 # If PEER is set, it must be a valid IP address
85 if isset PEER && ! ip_is_valid "${PEER}"; then
86 error "Peer ${PEER} is not a valid IP address"
87 return ${EXIT_ERROR}
88 fi
89
90 # If LOCAL_ADDRESS is set, it must be a valid IP address
91 # of the same protocol than PEER is
92 if isset LOCAL_ADDRESS; then
93 if ! ip_is_valid "${LOCAL_ADDRESS}"; then
94 error "Local address ${LOCAL_ADDRESS} is not a valid IP address"
95 return ${EXIT_ERROR}
96 fi
97
98 if ! ip_protocol_match "${PEER}" "${LOCAL_ADDRESS}"; then
99 error "Peer and local address are of different IP protocols"
100 return ${EXIT_ERROR}
101 fi
102 fi
103
104 return ${EXIT_OK}
105 }
106
107 hook_create() {
108 local port="${1}"
109 assert isset port
110
111 local ${HOOK_SETTINGS}
112 if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then
113 log ERROR "Could not read settings for port ${port}"
114 return ${EXIT_ERROR}
115 fi
116
117 if ! ip_tunnel_add "${port}" \
118 --mode="${MODE}" \
119 --address="${ADDRESS}" \
120 --remote-address="${PEER}" \
121 --local-address="${LOCAL_ADDRESS}" \
122 --ikey="${MARK}" \
123 --okey="${MARK}"; then
124 return ${EXIT_ERROR}
125 fi
126
127 exit ${EXIT_OK}
128 }
129
130 hook_remove() {
131 local port="${1}"
132 assert isset port
133
134 # Remove the device
135 if ! ip_tunnel_del "${port}"; then
136 return ${EXIT_ERROR}
137 fi
138
139 exit ${EXIT_OK}
140 }
141
142 hook_hotplug_rename() {
143 local port="${1}"
144 assert isset port
145
146 local device="${2}"
147 assert isset device
148
149 local ${HOOK_SETTINGS}
150 if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then
151 log ERROR "Could not read settings for port ${port}"
152 return ${EXIT_ERROR}
153 fi
154
155 # Get the current MAC address of the device.
156 local address="$(device_get_address ${device})"
157 assert isset address
158
159 # Return OK on match
160 if [ "${ADDRESS}" = "${address}" ]; then
161 return ${EXIT_OK}
162 fi
163
164 return ${EXIT_ERROR}
165 }