sgw: policy script: log invocations and add cleanup mode
[olsrd.git] / files / sgw_policy_routing_setup.sh
1 #!/bin/bash
2
3 set -e
4 set -u
5
6
7 declare script="$0"
8 declare scriptName="$(basename "${0%\.*}")"
9 declare -a arguments=( ${@} )
10 declare -i argc=$#
11
12
13 ###############################################################################
14 #
15 # OVERVIEW
16 #
17 ###############################################################################
18
19 # Tables (from SmartGatewayTablesOffset):
20 #                                               +-----------------+-----------------+---------------+
21 #                                               | sgwsrvtun table | egressif tables | sgwtun tables |
22 #                                               +-----------------+-----------------+---------------+
23 # Example:                                              90               91 92            93 94 ...
24 #
25 #
26 # Rules (from SmartGatewayRulesOffset):
27 # +-----------------------+---------------------+-----------------+-----------------+---------------+
28 # | egressif bypass rules | olsrif bypass rules | sgwsrvtun rule  | egressif rules  | sgwtun rules  |
29 # +-----------------------+---------------------+-----------------+-----------------+---------------+
30 # Example:  84 85               86 87 88 89             90               91 92            93 94 ...
31
32
33 ###############################################################################
34 #
35 # SETTINGS
36 #
37 ###############################################################################
38
39 declare IPVERSION_4="ipv4"
40 declare IPVERSION_6="ipv6"
41
42 declare MODE_CLEANUP="cleanup"
43 declare MODE_GENERIC="generic"
44 declare MODE_OLSRIF="olsrif"
45 declare MODE_SGWSRVTUN="sgwsrvtun"
46 declare MODE_EGRESSIF="egressif"
47 declare MODE_SGWTUN="sgwtun"
48
49 declare ADDMODE_ADD="add"
50 declare ADDMODE_DEL="del"
51
52 declare -i MODE_CLEANUP_ARGC=0
53 declare -i MODE_GENERIC_ARGC=0
54 declare -i MODE_OLSRIF_ARGC=2
55 declare -i MODE_EGRESSIF_ARGC=4
56 declare -i MODE_SGWSRVTUN_ARGC=3
57 declare -i MODE_SGWTUN_ARGC=3
58
59
60 ###############################################################################
61 #
62 # HELPER FUNCTIONS
63 #
64 ###############################################################################
65
66 function usage() {
67   echo ""
68   echo "The script was called as:"
69   echo "  $script ${arguments[@]:-}"
70   echo ""
71   echo "Usage:"
72   echo "  $script instanceId ipVersion mode addMode ifName tableNr ruleNr bypassRuleNr"
73   echo "    - instanceId  : the olsrd instance id"
74   echo "    - ipVersion   : $IPVERSION_4 or $IPVERSION_6"
75   echo "    - mode        : $MODE_CLEANUP, $MODE_GENERIC, $MODE_OLSRIF, $MODE_EGRESSIF, $MODE_SGWSRVTUN or $MODE_SGWTUN"
76   echo "    - addMode     : $ADDMODE_ADD or $ADDMODE_DEL"
77   echo "    - ifName      : the interface name       , only relevant for modes $MODE_EGRESSIF, $MODE_SGWSRVTUN, $MODE_SGWTUN"
78   echo "    - tableNr     : the routing table number , only relevant for modes $MODE_EGRESSIF, $MODE_SGWSRVTUN, $MODE_SGWTUN"
79   echo "    - ruleNr      : the ip rule number       , only relevant for modes $MODE_EGRESSIF, $MODE_SGWSRVTUN, $MODE_SGWTUN"
80   echo "    - bypassRuleNr: the bypass ip rule number, only relevant for mode  $MODE_EGRESSIF, $MODE_OLSRIF"
81 }
82
83 function error() {
84   local -i firstLine=1
85   while [ $# -gt 0 ]; do
86     if [ $firstLine -eq 1 ]; then
87       echo "Error: $1"
88     else
89       echo "       $1"
90     fi
91     firstLine=0
92     shift 1
93   done
94 }
95
96
97 ###############################################################################
98 #
99 # HELPER FUNCTIONS
100 #
101 ###############################################################################
102
103 function updateLogFile() {
104   local logLine="$ipVersion $mode $ADDMODE_DEL"
105   while [ $# -gt 0 ]; do
106     logLine="$logLine $1"
107     shift 1
108   done
109
110   echo "$logLine" >> "$logFile"
111 }
112
113
114 ###############################################################################
115 #
116 # MODE FUNCTIONS
117 #
118 ###############################################################################
119
120 function cleanup() {
121   if [ ! -e "$logFile" ]; then
122     return
123   fi
124
125   if [ "$addMode" = "$ADDMODE_ADD" ] && \
126      [ -s "$logFile" ]; then
127     # read logFile
128     local ifsOrg="$IFS"
129     IFS=$'\n'
130     local -a lines=( $(cat "$logFile" | sed -r '/^[[:space:]]*$/ d') )
131     IFS="$ifsOrg"
132
133     local -i index=${#lines[*]}
134     index+=-1
135     while [ $index -ge 0 ]; do
136       set +e
137       "$script" "$instanceId" ${lines[$index]}
138       set -e
139       index+=-1
140     done
141   fi
142
143   rm -f "$logFile"
144 }
145
146 function generic() {
147   "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" PREROUTING  -m conntrack ! --ctstate NEW -j CONNMARK --restore-mark
148   "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" OUTPUT      -m conntrack ! --ctstate NEW -j CONNMARK --restore-mark
149 }
150
151 function olsrif() {
152   local interfaceName="$1"
153   local bypassRuleNr="$2"
154
155   "$IP"       $IP_ARGS        rule      "$ADDMODE_IP" iif    "$interfaceName" table main       priority "$bypassRuleNr"
156 }
157
158 function egressif() {
159   local interfaceName="$1"
160   local tableNr="$2"
161   local ruleNr="$3"
162   local bypassRuleNr="$4"
163
164   "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" POSTROUTING -m conntrack --ctstate NEW -o "$interfaceName" -j CONNMARK --set-mark "$ruleNr"
165   "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" INPUT       -m conntrack --ctstate NEW -i "$interfaceName" -j CONNMARK --set-mark "$ruleNr"
166   "$IP"       $IP_ARGS       rule      "$ADDMODE_IP" fwmark "$ruleNr"        table "$tableNr" priority "$ruleNr"
167   "$IP"       $IP_ARGS       rule      "$ADDMODE_IP" iif    "$interfaceName" table main       priority "$bypassRuleNr"
168 }
169
170 function sgwsrvtun() {
171   local interfaceName="$1"
172   local tableNr="$2"
173   local ruleNr="$3"
174
175   "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" PREROUTING  -m conntrack --ctstate NEW -i "$interfaceName" -j CONNMARK --set-mark "$ruleNr"
176   "$IP"       $IP_ARGS       rule      "$ADDMODE_IP" fwmark "$ruleNr" table "$tableNr" priority "$ruleNr"
177 }
178
179 function sgwtun() {
180   local interfaceName="$1"
181   local tableNr="$2"
182   local ruleNr="$3"
183
184   "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" POSTROUTING -m conntrack --ctstate NEW -o "$interfaceName" -j CONNMARK --set-mark "$ruleNr"
185   "$IP"       $IP_ARGS       rule      "$ADDMODE_IP" fwmark "$ruleNr" table "$tableNr" priority "$ruleNr"
186 }
187
188
189 ###############################################################################
190 #
191 # MAIN
192 #
193 ###############################################################################
194
195 # we always need 4 arguments, check it
196 if [ $argc -lt 4 ]; then
197   error "Need at least 4 arguments"
198   usage
199   exit 1
200 fi
201
202 # get first 4 arguments
203 declare instanceId="$1"
204 declare ipVersion="$2"
205 declare mode="$3"
206 declare addMode="$4"
207 shift 4
208 declare logFile="/var/run/$scriptName-$instanceId.log"
209 argc=$#
210
211 # check IP version argument
212 if [ ! "$ipVersion" = "$IPVERSION_4" ] && \
213    [ ! "$ipVersion" = "$IPVERSION_6" ]; then
214   error "Illegal IP version"
215   usage
216   exit 1
217 fi
218
219 # check mode argument
220 if [ ! "$mode" = "$MODE_CLEANUP" ] && \
221    [ ! "$mode" = "$MODE_GENERIC" ] && \
222    [ ! "$mode" = "$MODE_OLSRIF" ] && \
223    [ ! "$mode" = "$MODE_SGWSRVTUN" ] && \
224    [ ! "$mode" = "$MODE_EGRESSIF" ] && \
225    [ ! "$mode" = "$MODE_SGWTUN" ]; then
226   error "Illegal mode"
227   usage
228   exit 1
229 fi
230
231 # check addMode argument
232 if [ ! "$addMode" = "$ADDMODE_ADD" ] && \
233    [ ! "$addMode" = "$ADDMODE_DEL" ]; then
234   error "Illegal addMode"
235   usage
236   exit 1
237 fi
238
239 # check argument count for all modes
240 if ([ "$mode" = "$MODE_CLEANUP" ]   && [ $argc -lt $MODE_CLEANUP_ARGC   ]) || \
241    ([ "$mode" = "$MODE_GENERIC" ]   && [ $argc -lt $MODE_GENERIC_ARGC   ]) || \
242    ([ "$mode" = "$MODE_OLSRIF" ]    && [ $argc -lt $MODE_OLSRIF_ARGC    ]) || \
243    ([ "$mode" = "$MODE_EGRESSIF"  ] && [ $argc -lt $MODE_EGRESSIF_ARGC  ]) || \
244    ([ "$mode" = "$MODE_SGWSRVTUN" ] && [ $argc -lt $MODE_SGWSRVTUN_ARGC ]) || \
245    ([ "$mode" = "$MODE_SGWTUN"  ]   && [ $argc -lt $MODE_SGWTUN_ARGC    ]); then
246   if [ $argc -eq 0 ]; then
247     error "Not enough arguments arguments ($argc) for mode $mode"
248   else
249     error "Not enough arguments arguments ($argc) for mode $mode" "Arguments: ${@}"
250   fi
251   usage
252   exit 1
253 fi
254
255 # check argument count for all modes
256 if ([ "$mode" = "$MODE_CLEANUP" ]   && [ $argc -gt $MODE_CLEANUP_ARGC   ]) || \
257    ([ "$mode" = "$MODE_GENERIC" ]   && [ $argc -gt $MODE_GENERIC_ARGC   ]) || \
258    ([ "$mode" = "$MODE_OLSRIF" ]    && [ $argc -gt $MODE_OLSRIF_ARGC    ]) || \
259    ([ "$mode" = "$MODE_EGRESSIF"  ] && [ $argc -gt $MODE_EGRESSIF_ARGC  ]) || \
260    ([ "$mode" = "$MODE_SGWSRVTUN" ] && [ $argc -gt $MODE_SGWSRVTUN_ARGC ]) || \
261    ([ "$mode" = "$MODE_SGWTUN"  ]   && [ $argc -gt $MODE_SGWTUN_ARGC    ]); then
262   if [ $argc -eq 0 ]; then
263     error "Too many arguments arguments ($argc) for mode $mode"
264   else
265     error "Too many arguments arguments ($argc) for mode $mode" "Arguments: ${@}"
266   fi
267   usage
268   exit 1
269 fi
270
271 # process ipVersion argument
272 declare IPTABLES="iptables"
273 declare IPTABLES_ARGS=""
274 declare IP="ip"
275 declare IP_ARGS="-4"
276 if [ "$ipVersion" = "$IPVERSION_6" ]; then
277   IPTABLES="ip6tables"
278   IPTABLES_ARGS=""
279   IP="ip"
280   IP_ARGS="-6"
281 fi
282
283 # process addMode argument
284 declare ADDMODE_IPTABLES="-D"
285 declare ADDMODE_IP="delete"
286 if [ "$addMode" = "$ADDMODE_ADD" ]; then
287   # first call the delete mode to remove any left-over rules
288   set +e
289   "$mode" "${@}" 2> /dev/null
290   set -e
291
292   ADDMODE_IPTABLES="-I"
293   ADDMODE_IP="add"
294 fi
295
296 # call the mode
297 if [ "$addMode" = "$ADDMODE_ADD" ] && [ ! "$mode" = "$MODE_CLEANUP" ]; then
298   updateLogFile "${@}"
299 fi
300 "$mode" "${@}"