sgw: rework policy rules setup
authorFerry Huberts <ferry.huberts@pelagic.nl>
Wed, 19 Mar 2014 10:23:04 +0000 (11:23 +0100)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Wed, 19 Mar 2014 10:30:23 +0000 (11:30 +0100)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
12 files changed:
README-Olsr-Extensions
files/olsrd.conf.default.full
files/olsrd.conf.default.lq
files/olsrd.conf.default.lq-fisheye
files/sgw_policy_routing_setup.sh
lib/jsoninfo/src/olsrd_jsoninfo.c
src/cfgparser/cfgfile_gen.c
src/cfgparser/olsrd_conf.c
src/cfgparser/oparse.y
src/cfgparser/oscan.lex
src/gateway.c
src/olsr_cfg.h

index a7515fc..103fb46 100644 (file)
@@ -275,12 +275,12 @@ All other parameters will be ignored if SmartGateway is set to "no"
    SmartGatewayUseCount is larger than 1 (in which case it must be explicitly
    set).
    The default setting is <not set>.
-5- SmartGatewayMarkOffsetServerTunnel, SmartGatewayMarkOffsetEgress and
-   SmartGatewayMarkOffsetTunnels determine the ranges of policy routing rule
-   markings that are used in a multi-gateway setup. The ranges are not allowed
-   to overlap. These settings are only relevant when a multi-gateway setup is
-   used.
-   The default settings are 90, 91 and 101 respectively.
+5- SmartGatewayTablesOffset and SmartGatewayRulesOffset determine the ranges of
+   policy routing rule markings that are used in a multi-gateway setup (see the
+   policy routing script for an explanation).
+   The default settings are 90 and 0 respectively. The value of 0 for
+   SmartGatewayRulesOffset will automatically align the table and rule numbers
+   for the server tunnel, egress interfaces and gateway tunnel interfaces.
 6- SmartGatewayAllowNAT controls whether you want to allow the selection
    of an outgoing ipv4 gateway with NAT (Network Address Translation).
    The default setting is "yes".
index 9491d9c..2e2e648 100644 (file)
 
 # SmartGatewayEgressInterfaces ""
 
-# Determines the offset of the smart gateway server tunnel interface mark that
-# is used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
+# Determines the routing tables offset for multi-gateway policy routing tables
+# See the policy routing script for an explanation.
 # (default is 90)
 
-# SmartGatewayMarkOffsetServerTunnel 90
+# SmartGatewayTablesOffset 90
 
-# Determines the offset of the smart gateway egress interfaces mark that are
-# used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
-# (default is 91)
+# Determines the policy routing rules offset for multi-gateway policy routing
+# rules. See the policy routing script for an explanation.
+# (default is 0, which indicates that the rules and tables should be aligned and
+# puts this value at SmartGatewayTablesOffset - # egress interfaces -
+# # olsr interfaces)
 
-# SmartGatewayMarkOffsetEgress 91
-
-# Determines the offset of the smart gateway tunnel interfaces mark that are
-# used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
-# The ranges [egress offset, egress offset + egress count] and
-# [tunnel offset, tunnel offset + use count] are not allowed to overlap.
-# (default is 101)
-
-# SmartGatewayMarkOffsetTunnels 101
+# SmartGatewayRulesOffset 87
 
 # Allows the selection of a smartgateway with NAT (only for IPv4)
 # (default is "yes")
index 6618c1e..e694e3d 100644 (file)
 
 # SmartGatewayEgressInterfaces ""
 
-# Determines the offset of the smart gateway server tunnel interface mark that
-# is used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
+# Determines the routing tables offset for multi-gateway policy routing tables
+# See the policy routing script for an explanation.
 # (default is 90)
 
-# SmartGatewayMarkOffsetServerTunnel 90
+# SmartGatewayTablesOffset 90
 
-# Determines the offset of the smart gateway egress interfaces mark that are
-# used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
-# (default is 91)
+# Determines the policy routing rules offset for multi-gateway policy routing
+# rules. See the policy routing script for an explanation.
+# (default is 0, which indicates that the rules and tables should be aligned and
+# puts this value at SmartGatewayTablesOffset - # egress interfaces -
+# # olsr interfaces)
 
-# SmartGatewayMarkOffsetEgress 91
-
-# Determines the offset of the smart gateway tunnel interfaces mark that are
-# used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
-# The ranges [egress offset, egress offset + egress count] and
-# [tunnel offset, tunnel offset + use count] are not allowed to overlap.
-# (default is 101)
-
-# SmartGatewayMarkOffsetTunnels 101
+# SmartGatewayRulesOffset 87
 
 # Allows the selection of a smartgateway with NAT (only for IPv4)
 # (default is "yes")
index 0b7bd49..2b5587b 100644 (file)
 
 # SmartGatewayEgressInterfaces ""
 
-# Determines the offset of the smart gateway server tunnel interface mark that
-# is used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
+# Determines the routing tables offset for multi-gateway policy routing tables
+# See the policy routing script for an explanation.
 # (default is 90)
 
-# SmartGatewayMarkOffsetServerTunnel 90
+# SmartGatewayTablesOffset 90
 
-# Determines the offset of the smart gateway egress interfaces mark that are
-# used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
-# (default is 91)
+# Determines the policy routing rules offset for multi-gateway policy routing
+# rules. See the policy routing script for an explanation.
+# (default is 0, which indicates that the rules and tables should be aligned and
+# puts this value at SmartGatewayTablesOffset - # egress interfaces -
+# # olsr interfaces)
 
-# SmartGatewayMarkOffsetEgress 91
-
-# Determines the offset of the smart gateway tunnel interfaces mark that are
-# used in the policy routing rules in a multi-gateway setup. Only relevant
-# when a multi-gateway setup is used.
-# The ranges [egress offset, egress offset + egress count] and
-# [tunnel offset, tunnel offset + use count] are not allowed to overlap.
-# (default is 101)
-
-# SmartGatewayMarkOffsetTunnels 101
+# SmartGatewayRulesOffset 87
 
 # Allows the selection of a smartgateway with NAT (only for IPv4)
 # (default is "yes")
index 9b4c737..8fdc4a1 100755 (executable)
@@ -3,6 +3,27 @@
 set -e
 set -u
 
+
+###############################################################################
+#
+# OVERVIEW
+#
+###############################################################################
+
+# Tables (from SmartGatewayTablesOffset):
+#                                               +-----------------+-----------------+---------------+
+#                                               | sgwsrvtun table | egressif tables | sgwtun tables |
+#                                               +-----------------+-----------------+---------------+
+# Example:                                              90               91 92            93 94 ...
+#
+#
+# Rules (from SmartGatewayRulesOffset):
+# +-----------------------+---------------------+-----------------+-----------------+---------------+
+# | egressif bypass rules | olsrif bypass rules | sgwsrvtun rule  | egressif rules  | sgwtun rules  |
+# +-----------------------+---------------------+-----------------+-----------------+---------------+
+# Example:  84 85               86 87 88 89             90               91 92            93 94 ...
+
+
 ###############################################################################
 #
 # SETTINGS
@@ -21,6 +42,12 @@ declare MODE_SGWTUN="sgwtun"
 declare ADDMODE_ADD="add"
 declare ADDMODE_DEL="del"
 
+declare -i MODE_GENERIC_ARGC=0
+declare -i MODE_OLSRIF_ARGC=2
+declare -i MODE_EGRESSIF_ARGC=4
+declare -i MODE_SGWSRVTUN_ARGC=3
+declare -i MODE_SGWTUN_ARGC=3
+
 
 ###############################################################################
 #
@@ -31,24 +58,26 @@ declare ADDMODE_DEL="del"
 function usage() {
   echo ""
   echo "The script was called as:"
-  echo "  ${script} ${arguments[@]:-}"
+  echo "  $script ${arguments[@]:-}"
   echo ""
   echo "Usage:"
-  echo "  ${script} ipVersion mode addMode [ifname [ifmark]]"
-  echo "    - ipVersion: ${IPVERSION_4} or ${IPVERSION_6}"
-  echo "    - mode     : ${MODE_GENERIC}, ${MODE_OLSRIF}, ${MODE_SGWSRVTUN}, ${MODE_EGRESSIF} or ${MODE_SGWTUN}"
-  echo "    - addMode  : ${ADDMODE_ADD} or ${ADDMODE_DEL}"
-  echo "    - ifname   : an interface name, not relevant for generic mode"
-  echo "    - ifmark   : an interface marking (number), only relevant for modes ${MODE_SGWSRVTUN}, ${MODE_EGRESSIF} and ${MODE_SGWTUN}"
+  echo "  $script ipVersion mode addMode ifName tableNr ruleNr bypassRuleNr"
+  echo "    - ipVersion   : $IPVERSION_4 or $IPVERSION_6"
+  echo "    - mode        : $MODE_GENERIC, $MODE_OLSRIF, $MODE_EGRESSIF, $MODE_SGWSRVTUN or $MODE_SGWTUN"
+  echo "    - addMode     : $ADDMODE_ADD or $ADDMODE_DEL"
+  echo "    - ifName      : the interface name       , only relevant for modes $MODE_EGRESSIF, $MODE_SGWSRVTUN, $MODE_SGWTUN"
+  echo "    - tableNr     : the routing table number , only relevant for modes $MODE_EGRESSIF, $MODE_SGWSRVTUN, $MODE_SGWTUN"
+  echo "    - ruleNr      : the ip rule number       , only relevant for modes $MODE_EGRESSIF, $MODE_SGWSRVTUN, $MODE_SGWTUN"
+  echo "    - bypassRuleNr: the bypass ip rule number, only relevant for mode  $MODE_EGRESSIF, $MODE_OLSRIF"
 }
 
 function error() {
   local -i firstLine=1
-  while [ ${#} -gt 0 ]; do
-    if [ ${firstLine} -eq 1 ]; then
-      echo "Error: ${1}"
+  while [ $# -gt 0 ]; do
+    if [ $firstLine -eq 1 ]; then
+      echo "Error: $1"
     else
-      echo "       ${1}"
+      echo "       $1"
     fi
     firstLine=0
     shift 1
@@ -63,29 +92,45 @@ function error() {
 ###############################################################################
 
 function generic() {
-  "${IPTABLES}" ${IPTABLES_ARGS} -t mangle "${ADDMODE_IPTABLES}" PREROUTING  -m conntrack ! --ctstate NEW -j CONNMARK --restore-mark
-  "${IPTABLES}" ${IPTABLES_ARGS} -t mangle "${ADDMODE_IPTABLES}" OUTPUT      -m conntrack ! --ctstate NEW -j CONNMARK --restore-mark
+  "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" PREROUTING  -m conntrack ! --ctstate NEW -j CONNMARK --restore-mark
+  "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" OUTPUT      -m conntrack ! --ctstate NEW -j CONNMARK --restore-mark
 }
 
 function olsrif() {
-  # do nothing
-  echo -n "" > /dev/null
-}
+  local interfaceName="$1"
+  local bypassRuleNr="$2"
 
-function sgwsrvtun() {
-  "${IPTABLES}" ${IPTABLES_ARGS} -t mangle "${ADDMODE_IPTABLES}" PREROUTING  -m conntrack --ctstate NEW -i "${1}" -j CONNMARK --set-mark "${2}"
-  "${IP}" ${IP_ARGS} rule "${ADDMODE_IP}" fwmark "${2}" table "${2}" pref "${2}"
+  "$IP"       $IP_ARGS        rule      "$ADDMODE_IP" iif    "$interfaceName" table main       priority "$bypassRuleNr"
 }
 
 function egressif() {
-  "${IPTABLES}" ${IPTABLES_ARGS} -t mangle "${ADDMODE_IPTABLES}" POSTROUTING -m conntrack --ctstate NEW -o "${1}" -j CONNMARK --set-mark "${2}"
-  "${IPTABLES}" ${IPTABLES_ARGS} -t mangle "${ADDMODE_IPTABLES}" INPUT       -m conntrack --ctstate NEW -i "${1}" -j CONNMARK --set-mark "${2}"
-  "${IP}" ${IP_ARGS} rule "${ADDMODE_IP}" fwmark "${2}" table "${2}" pref "${2}"
+  local interfaceName="$1"
+  local tableNr="$2"
+  local ruleNr="$3"
+  local bypassRuleNr="$4"
+
+  "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" POSTROUTING -m conntrack --ctstate NEW -o "$interfaceName" -j CONNMARK --set-mark "$ruleNr"
+  "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" INPUT       -m conntrack --ctstate NEW -i "$interfaceName" -j CONNMARK --set-mark "$ruleNr"
+  "$IP"       $IP_ARGS       rule      "$ADDMODE_IP" fwmark "$ruleNr"        table "$tableNr" priority "$ruleNr"
+  "$IP"       $IP_ARGS       rule      "$ADDMODE_IP" iif    "$interfaceName" table main       priority "$bypassRuleNr"
+}
+
+function sgwsrvtun() {
+  local interfaceName="$1"
+  local tableNr="$2"
+  local ruleNr="$3"
+
+  "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" PREROUTING  -m conntrack --ctstate NEW -i "$interfaceName" -j CONNMARK --set-mark "$ruleNr"
+  "$IP"       $IP_ARGS       rule      "$ADDMODE_IP" fwmark "$ruleNr" table "$tableNr" priority "$ruleNr"
 }
 
 function sgwtun() {
-  "${IPTABLES}" ${IPTABLES_ARGS} -t mangle "${ADDMODE_IPTABLES}" POSTROUTING -m conntrack --ctstate NEW -o "${1}" -j CONNMARK --set-mark "${2}"
-  "${IP}" ${IP_ARGS} rule "${ADDMODE_IP}" fwmark "${2}" table "${2}" pref "${2}"
+  local interfaceName="$1"
+  local tableNr="$2"
+  local ruleNr="$3"
+
+  "$IPTABLES" $IPTABLES_ARGS -t mangle "$ADDMODE_IPTABLES" POSTROUTING -m conntrack --ctstate NEW -o "$interfaceName" -j CONNMARK --set-mark "$ruleNr"
+  "$IP"       $IP_ARGS       rule      "$ADDMODE_IP" fwmark "$ruleNr" table "$tableNr" priority "$ruleNr"
 }
 
 
@@ -95,58 +140,77 @@ function sgwtun() {
 #
 ###############################################################################
 
-declare script="${0}"
+declare script="$0"
 declare -a arguments=( ${@} )
-declare -i argc=${#}
+declare -i argc=$#
 
 # we always need 3 arguments, check it
-if [ ${argc} -lt 3 ]; then
+if [ $argc -lt 3 ]; then
   error "Need at least 3 arguments"
   usage
   exit 1
 fi
 
 # get first 3 arguments
-declare ipVersion=${1}
-declare mode="${2}"
-declare addMode="${3}"
+declare ipVersion=$1
+declare mode="$2"
+declare addMode="$3"
 shift 3
-argc=${#}
+argc=$#
 
 # check IP version argument
-if [ ! "${ipVersion}" == "${IPVERSION_4}" ] && \
-   [ ! "${ipVersion}" == "${IPVERSION_6}" ]; then
+if [ ! "$ipVersion" == "$IPVERSION_4" ] && \
+   [ ! "$ipVersion" == "$IPVERSION_6" ]; then
   error "Illegal IP version"
   usage
   exit 1
 fi
 
 # check mode argument
-if [ ! "${mode}" == "${MODE_GENERIC}" ] && \
-   [ ! "${mode}" == "${MODE_OLSRIF}" ] && \
-   [ ! "${mode}" == "${MODE_SGWSRVTUN}" ] && \
-   [ ! "${mode}" == "${MODE_EGRESSIF}" ] && \
-   [ ! "${mode}" == "${MODE_SGWTUN}" ]; then
+if [ ! "$mode" == "$MODE_GENERIC" ] && \
+   [ ! "$mode" == "$MODE_OLSRIF" ] && \
+   [ ! "$mode" == "$MODE_SGWSRVTUN" ] && \
+   [ ! "$mode" == "$MODE_EGRESSIF" ] && \
+   [ ! "$mode" == "$MODE_SGWTUN" ]; then
   error "Illegal mode"
   usage
   exit 1
 fi
 
 # check addMode argument
-if [ ! "${addMode}" == "${ADDMODE_ADD}" ] && \
-   [ ! "${addMode}" == "${ADDMODE_DEL}" ]; then
+if [ ! "$addMode" == "$ADDMODE_ADD" ] && \
+   [ ! "$addMode" == "$ADDMODE_DEL" ]; then
   error "Illegal addMode"
   usage
   exit 1
 fi
 
 # check argument count for all modes
-if ([ "${mode}" == "${MODE_GENERIC}" ]   && [ ${argc} -ne 0 ]) || \
-   ([ "${mode}" == "${MODE_OLSRIF}" ]    && [ ${argc} -ne 1 ]) || \
-   ([ "${mode}" == "${MODE_SGWSRVTUN}" ] && [ ${argc} -ne 2 ]) || \
-   ([ "${mode}" == "${MODE_EGRESSIF}"  ] && [ ${argc} -ne 2 ]) || \
-   ([ "${mode}" == "${MODE_SGWTUN}"  ]   && [ ${argc} -ne 2 ]); then
-  error "Not enough arguments or too many arguments"
+if ([ "$mode" == "$MODE_GENERIC" ]   && [ $argc -lt $MODE_GENERIC_ARGC   ]) || \
+   ([ "$mode" == "$MODE_OLSRIF" ]    && [ $argc -lt $MODE_OLSRIF_ARGC    ]) || \
+   ([ "$mode" == "$MODE_EGRESSIF"  ] && [ $argc -lt $MODE_EGRESSIF_ARGC  ]) || \
+   ([ "$mode" == "$MODE_SGWSRVTUN" ] && [ $argc -lt $MODE_SGWSRVTUN_ARGC ]) || \
+   ([ "$mode" == "$MODE_SGWTUN"  ]   && [ $argc -lt $MODE_SGWTUN_ARGC    ]); then
+  if [ $argc -eq 0 ]; then
+    error "Not enough arguments arguments ($argc) for mode $mode"
+  else
+    error "Not enough arguments arguments ($argc) for mode $mode" "Arguments: ${@}"
+  fi
+  usage
+  exit 1
+fi
+
+# check argument count for all modes
+if ([ "$mode" == "$MODE_GENERIC" ]   && [ $argc -gt $MODE_GENERIC_ARGC   ]) || \
+   ([ "$mode" == "$MODE_OLSRIF" ]    && [ $argc -gt $MODE_OLSRIF_ARGC    ]) || \
+   ([ "$mode" == "$MODE_EGRESSIF"  ] && [ $argc -gt $MODE_EGRESSIF_ARGC  ]) || \
+   ([ "$mode" == "$MODE_SGWSRVTUN" ] && [ $argc -gt $MODE_SGWSRVTUN_ARGC ]) || \
+   ([ "$mode" == "$MODE_SGWTUN"  ]   && [ $argc -gt $MODE_SGWTUN_ARGC    ]); then
+  if [ $argc -eq 0 ]; then
+    error "Not enough arguments arguments ($argc) for mode $mode"
+  else
+    error "Not enough arguments arguments ($argc) for mode $mode" "Arguments: ${@}"
+  fi
   usage
   exit 1
 fi
@@ -156,7 +220,7 @@ declare IPTABLES="iptables"
 declare IPTABLES_ARGS=""
 declare IP="ip"
 declare IP_ARGS="-4"
-if [ "${ipVersion}" == "${IPVERSION_6}" ]; then
+if [ "$ipVersion" == "$IPVERSION_6" ]; then
   IPTABLES="ip6tables"
   IPTABLES_ARGS=""
   IP="ip"
@@ -166,10 +230,10 @@ fi
 # process addMode argument
 declare ADDMODE_IPTABLES="-D"
 declare ADDMODE_IP="delete"
-if [ "${addMode}" == "${ADDMODE_ADD}" ]; then
+if [ "$addMode" == "$ADDMODE_ADD" ]; then
   # first call the delete mode to remove any left-over rules
   set +e
-  "${mode}" "${@}" 2> /dev/null
+  "$mode" "${@}" 2> /dev/null
   set -e
 
   ADDMODE_IPTABLES="-I"
@@ -177,4 +241,4 @@ if [ "${addMode}" == "${ADDMODE_ADD}" ]; then
 fi
 
 # call the mode
-"${mode}" "${@}"
+"$mode" "${@}"
index a6f85fe..9ad76d0 100644 (file)
@@ -1006,9 +1006,8 @@ ipc_print_config(struct autobuf *abuf)
       abuf_json_string(abuf, "smartGatewayEgressInterfaces", egressbuf.buf);
       abuf_free(&egressbuf);
     }
-    abuf_json_int(abuf, "smartGatewayMarkOffsetServerTunnel", olsr_cnf->smart_gw_mark_offset_srvtun);
-    abuf_json_int(abuf, "smartGatewayMarkOffsetEgress", olsr_cnf->smart_gw_mark_offset_egress);
-    abuf_json_int(abuf, "smartGatewayMarkOffsetTunnels", olsr_cnf->smart_gw_mark_offset_tunnels);
+    abuf_json_int(abuf, "smartGatewayTablesOffset", olsr_cnf->smart_gw_offset_tables);
+    abuf_json_int(abuf, "smartGatewayRulesOffset", olsr_cnf->smart_gw_offset_rules);
     abuf_json_boolean(abuf, "smartGatewayAllowNat", olsr_cnf->smart_gw_allow_nat);
     abuf_json_boolean(abuf, "smartGatewayUplinkNat", olsr_cnf->smart_gw_uplink_nat);
     abuf_json_int(abuf, "smartGatewayPeriod", olsr_cnf->smart_gw_period);
index 3b3032f..de07d3a 100644 (file)
@@ -569,36 +569,24 @@ void olsrd_write_cnf_autobuf(struct autobuf *out, struct olsrd_config *cnf) {
   }
   abuf_appendf(out,
     "\n"
-    "# Determines the offset of the smart gateway server tunnel interface mark that\n"
-    "# is used in the policy routing rules in a multi-gateway setup. Only relevant\n"
-    "# when a multi-gateway setup is used.\n"
+    "# Determines the routing tables offset for multi-gateway policy routing tables\n"
+    "# See the policy routing script for an explanation.\n"
     "# (default is %u)\n"
-    "\n", DEF_GW_MARK_OFFSET_SRVTUN);
-  abuf_appendf(out, "%sSmartGatewayMarkOffsetServerTunnel %u\n",
-      cnf->smart_gw_mark_offset_srvtun == DEF_GW_MARK_OFFSET_SRVTUN ? "# " : "",
-      cnf->smart_gw_mark_offset_srvtun);
-  abuf_appendf(out,
-    "\n"
-    "# Determines the offset of the smart gateway egress interfaces mark that are\n"
-    "# used in the policy routing rules in a multi-gateway setup. Only relevant\n"
-    "# when a multi-gateway setup is used.\n"
-    "# (default is %u)\n"
-    "\n", DEF_GW_MARK_OFFSET_EGRESS);
-  abuf_appendf(out, "%sSmartGatewayMarkOffsetEgress %u\n",
-      cnf->smart_gw_mark_offset_egress == DEF_GW_MARK_OFFSET_EGRESS ? "# " : "",
-      cnf->smart_gw_mark_offset_egress);
-  abuf_appendf(out,
-    "\n"
-    "# Determines the offset of the smart gateway tunnel interfaces mark that are\n"
-    "# used in the policy routing rules in a multi-gateway setup. Only relevant\n"
-    "# when a multi-gateway setup is used.\n"
-    "# The ranges [egress offset, egress offset + egress count] and\n"
-    "# [tunnel offset, tunnel offset + use count] are not allowed to overlap.\n"
-    "# (default is %u)\n"
-    "\n", DEF_GW_MARK_OFFSET_TUNNELS);
-  abuf_appendf(out, "%sSmartGatewayMarkOffsetTunnels %u\n",
-      cnf->smart_gw_mark_offset_tunnels == DEF_GW_MARK_OFFSET_TUNNELS ? "# " : "",
-      cnf->smart_gw_mark_offset_tunnels);
+    "\n", DEF_GW_OFFSET_TABLES);
+  abuf_appendf(out, "%sSmartGatewayTablesOffset %u\n",
+      cnf->smart_gw_offset_tables == DEF_GW_OFFSET_TABLES ? "# " : "",
+      cnf->smart_gw_offset_tables);
+  abuf_appendf(out,
+    "\n"
+    "# Determines the policy routing rules offset for multi-gateway policy routing\n"
+    "# rules. See the policy routing script for an explanation.\n"
+    "# (default is %u, which indicates that the rules and tables should be aligned and\n"
+    "# puts this value at SmartGatewayTablesOffset - # egress interfaces -\n"
+    "# # olsr interfaces)\n"
+    "\n", DEF_GW_OFFSET_RULES);
+  abuf_appendf(out, "%sSmartGatewayRulesOffset %u\n",
+      cnf->smart_gw_offset_rules == DEF_GW_OFFSET_RULES ? "# " : "",
+      cnf->smart_gw_offset_rules);
   abuf_appendf(out,
     "\n"
     "# Allows the selection of a smartgateway with NAT (only for IPv4)\n"
index bc63523..c68d244 100644 (file)
 extern FILE *yyin;
 extern int yyparse(void);
 
+#define valueInRange(value, low, high) ((low <= value) && (value <= high))
+
+#define rangesOverlap(low1, high1, low2, high2) ( \
+            valueInRange(low1 , low2, high2) || valueInRange(high1, low2, high2) || \
+            valueInRange(low2,  low1, high1) || valueInRange(high2, low1, high1))
+
 static char interface_defaults_name[] = "[InterfaceDefaults]";
 
 const char *FIB_METRIC_TXT[] = {
@@ -635,54 +641,76 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
     }
 
     {
-      uint8_t srvtun = cnf->smart_gw_mark_offset_srvtun;
-      uint8_t egressLow = cnf->smart_gw_mark_offset_egress;
-      uint8_t egressHigh = egressLow + cnf->smart_gw_egress_interfaces_count - 1;
-      uint8_t tunnelsLow = cnf->smart_gw_mark_offset_tunnels;
-      uint8_t tunnelsHigh = tunnelsLow + cnf->smart_gw_use_count - 1;
-      bool overlap = false;
-
-      /* check that the egress interface marks range does not overflow */
-      if (egressLow > (UINT8_MAX - cnf->smart_gw_egress_interfaces_count)) {
-        fprintf(stderr, "Error, egress interface mark offset %u together with egress interface count %u overflows range [0, %u]\n",
-            egressLow, cnf->smart_gw_egress_interfaces_count, UINT8_MAX);
+      uint32_t nrOfTables = 1 + cnf->smart_gw_egress_interfaces_count + cnf->smart_gw_use_count;
+
+      uint32_t nrOfBypassRules = cnf->smart_gw_egress_interfaces_count + getNrOfOlsrInterfaces(olsr_cnf);
+      uint32_t nrOfTableRules = nrOfTables;
+      uint32_t nrOfRules = nrOfBypassRules + nrOfTableRules;
+
+      uint32_t tablesLow;
+      uint32_t tablesHigh;
+      uint32_t tablesLowMax = ((1 << 31) - nrOfTables + 1);
+
+      uint32_t rulesLow;
+      uint32_t rulesHigh;
+      uint32_t rulesLowMax = UINT32_MAX - nrOfRules;
+
+      /* setup tables low/high */
+      tablesLow = cnf->smart_gw_offset_tables;
+      tablesHigh = cnf->smart_gw_offset_tables + nrOfTables;
+
+      /*
+       * tablesLow  >  0
+       * tablesLow  >  0
+       * tablesHigh <= 2^31
+       * [tablesLow, tablesHigh] no overlap with [253, 255]
+       */
+      if (!tablesLow) {
+        fprintf(stderr, "Error, smart gateway tables offset can't be zero.\n");
         return -1;
       }
 
-      /* check that the tunnel interface marks range does not overflow */
-      if (tunnelsLow > (UINT8_MAX - cnf->smart_gw_use_count)) {
-        fprintf(stderr, "Error, tunnel interface mark offset %u together with use count %u overflows range [0, %u]\n",
-            tunnelsLow, cnf->smart_gw_use_count, UINT8_MAX);
+      if (tablesLow > tablesLowMax) {
+        fprintf(stderr, "Error, smart gateway tables offset too large, maximum is %ul.\n", tablesLowMax);
         return -1;
       }
 
-#define valueInRange(value, low, high) ((low <= value) && (value <= high))
+      if (rangesOverlap(tablesLow, tablesHigh, 253, 255)) {
+        fprintf(stderr, "Error, smart gateway tables range [%u, %u] overlaps with routing tables [253, 255].\n", tablesLow, tablesHigh);
+        return -1;
+      }
 
-#define rangesOverlap(low1, high1, low2, high2) ( \
-                     valueInRange(low1 , low2, high2) || valueInRange(high1, low2, high2) || \
-                     valueInRange(low2,  low1, high1) || valueInRange(high2, low1, high1))
-
-      /* check that the server tunnel mark is not in the egress interface mark ranges */
-      overlap = valueInRange(srvtun, egressLow, egressHigh);
-      if (overlap) {
-        fprintf(stderr, "Error, server tunnel mark %u is in the egress interface mark range [%u, %u]\n",
-            srvtun, egressLow, egressHigh);
+      /* set default for rules offset if needed */
+      if (cnf->smart_gw_offset_rules == 0) {
+        if (valueInRange(tablesLow, 1, nrOfBypassRules)) {
+          fprintf(stderr, "Error, smart gateway table offset is too low: %u bypass rules won't fit between it and zero.\n", nrOfBypassRules);
+          return -1;
+        }
+
+        cnf->smart_gw_offset_rules = tablesLow - nrOfBypassRules;
+      }
+
+      /* setup rules low/high */
+      rulesLow = cnf->smart_gw_offset_rules;
+      rulesHigh = cnf->smart_gw_offset_rules + nrOfRules;
+
+      /*
+       * rulesLow  > 0
+       * rulesHigh < 2^32
+       * [rulesLow, rulesHigh] no overlap with [32766, 32767]
+       */
+      if (!rulesLow) {
+        fprintf(stderr, "Error, smart gateway rules offset can't be zero.\n");
         return -1;
       }
 
-      /* check that the server tunnel mark is not in the tunnel interface mark ranges */
-      overlap = valueInRange(srvtun, tunnelsLow, tunnelsHigh);
-      if (overlap) {
-        fprintf(stderr, "Error, server tunnel mark %u is in the tunnel interface mark range [%u, %u]\n",
-            srvtun, tunnelsLow, tunnelsHigh);
+      if (rulesLow > rulesLowMax) {
+        fprintf(stderr, "Error, smart gateway rules offset too large, maximum is %ul.\n", rulesLowMax);
         return -1;
       }
 
-      /* check that the egress and tunnel marks ranges do not overlap */
-      overlap = rangesOverlap(egressLow, egressHigh, tunnelsLow, tunnelsHigh);
-      if (overlap) {
-        fprintf(stderr, "Error, egress interface mark range [%u, %u] overlaps with tunnel interface mark range [%u, %u]\n",
-            egressLow, egressHigh, tunnelsLow, tunnelsHigh);
+      if (rangesOverlap(rulesLow, rulesHigh, 32766, 32767)) {
+        fprintf(stderr, "Error, smart gateway rules range [%u, %u] overlaps with rules [32766, 32767].\n", rulesLow, rulesHigh);
         return -1;
       }
     }
@@ -928,9 +956,8 @@ set_default_cnf(struct olsrd_config *cnf)
   cnf->smart_gw_policyrouting_script = NULL;
   cnf->smart_gw_egress_interfaces = NULL;
   cnf->smart_gw_egress_interfaces_count = 0;
-  cnf->smart_gw_mark_offset_srvtun = DEF_GW_MARK_OFFSET_SRVTUN;
-  cnf->smart_gw_mark_offset_egress = DEF_GW_MARK_OFFSET_EGRESS;
-  cnf->smart_gw_mark_offset_tunnels = DEF_GW_MARK_OFFSET_TUNNELS;
+  cnf->smart_gw_offset_tables = DEF_GW_OFFSET_TABLES;
+  cnf->smart_gw_offset_rules = DEF_GW_OFFSET_RULES;
   cnf->smart_gw_allow_nat = DEF_GW_ALLOW_NAT;
   cnf->smart_gw_period = DEF_GW_PERIOD;
   cnf->smart_gw_stablecount = DEF_GW_STABLE_COUNT;
@@ -1077,11 +1104,9 @@ olsrd_print_cnf(struct olsrd_config *cnf)
   }
   printf("\n");
 
-  printf("SmGw. Mark SrvTun: %u\n", cnf->smart_gw_mark_offset_srvtun);
-
-  printf("SmGw. Mark Egress: %u\n", cnf->smart_gw_mark_offset_egress);
+  printf("SmGw. Offst Tabls: %u\n", cnf->smart_gw_offset_tables);
 
-  printf("SmGw. Mark Tunnel: %u\n", cnf->smart_gw_mark_offset_tunnels);
+  printf("SmGw. Offst Rules: %u\n", cnf->smart_gw_offset_rules);
 
   printf("SmGw. Allow NAT  : %s\n", cnf->smart_gw_allow_nat ? "yes" : "no");
 
index 7841ee9..1ace8ca 100644 (file)
@@ -221,9 +221,8 @@ static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
 %token TOK_SMART_GW_TAKEDOWN_PERCENTAGE
 %token TOK_SMART_GW_POLICYROUTING_SCRIPT
 %token TOK_SMART_GW_EGRESS_IFS
-%token TOK_SMART_GW_MARK_OFFSET_SRVTUN
-%token TOK_SMART_GW_MARK_OFFSET_EGRESS
-%token TOK_SMART_GW_MARK_OFFSET_TUNNELS
+%token TOK_SMART_GW_OFFSET_TABLES
+%token TOK_SMART_GW_OFFSET_RULES
 %token TOK_SMART_GW_ALLOW_NAT
 %token TOK_SMART_GW_PERIOD
 %token TOK_SMART_GW_STABLECOUNT
@@ -315,9 +314,8 @@ stmt:       idebug
           | ismart_gw_use_count
           | ismart_gw_takedown_percentage
           | ssmart_gw_policyrouting_script
-          | ismart_gw_mark_offset_srvtun
-          | ismart_gw_mark_offset_egress
-          | ismart_gw_mark_offset_tunnels
+          | ismart_gw_offset_tables
+          | ismart_gw_offset_rules
           | bsmart_gw_allow_nat
           | ismart_gw_period
           | asmart_gw_stablecount
@@ -1433,26 +1431,18 @@ sgw_egress_if: TOK_STRING
 }
 ;
 
-ismart_gw_mark_offset_srvtun: TOK_SMART_GW_MARK_OFFSET_SRVTUN TOK_INTEGER
+ismart_gw_offset_tables: TOK_SMART_GW_OFFSET_TABLES TOK_INTEGER
 {
-  PARSER_DEBUG_PRINTF("Smart gateway mark offset server tunnel interface: %d\n", $2->integer);
-  olsr_cnf->smart_gw_mark_offset_srvtun = $2->integer;
+  PARSER_DEBUG_PRINTF("Smart gateway tables offset: %d\n", $2->integer);
+  olsr_cnf->smart_gw_offset_tables = $2->integer;
   free($2);
 }
 ;
 
-ismart_gw_mark_offset_egress: TOK_SMART_GW_MARK_OFFSET_EGRESS TOK_INTEGER
+ismart_gw_offset_rules: TOK_SMART_GW_OFFSET_RULES TOK_INTEGER
 {
-  PARSER_DEBUG_PRINTF("Smart gateway mark offset egress interfaces: %d\n", $2->integer);
-  olsr_cnf->smart_gw_mark_offset_egress = $2->integer;
-  free($2);
-}
-;
-
-ismart_gw_mark_offset_tunnels: TOK_SMART_GW_MARK_OFFSET_TUNNELS TOK_INTEGER
-{
-  PARSER_DEBUG_PRINTF("Smart gateway mark offset tunnel interfaces: %d\n", $2->integer);
-  olsr_cnf->smart_gw_mark_offset_tunnels = $2->integer;
+  PARSER_DEBUG_PRINTF("Smart gateway rules offset: %d\n", $2->integer);
+  olsr_cnf->smart_gw_offset_rules = $2->integer;
   free($2);
 }
 ;
index 169a67b..f909f27 100644 (file)
@@ -491,19 +491,14 @@ IPV6ADDR {IPV6PAT1}|{IPV6PAT2}|{IPV6PAT3}|{IPV6PAT4}|{IPV6PAT5}|{IPV6PAT6}|{IPV6
     return TOK_SMART_GW_EGRESS_IFS;
 }
 
-"SmartGatewayMarkOffsetServerTunnel" {
+"SmartGatewayTablesOffset" {
     yylval = NULL;
-    return TOK_SMART_GW_MARK_OFFSET_SRVTUN;
+    return TOK_SMART_GW_OFFSET_TABLES;
 }
 
-"SmartGatewayMarkOffsetEgress" {
+"SmartGatewayRulesOffset" {
     yylval = NULL;
-    return TOK_SMART_GW_MARK_OFFSET_EGRESS;
-}
-
-"SmartGatewayMarkOffsetTunnels" {
-    yylval = NULL;
-    return TOK_SMART_GW_MARK_OFFSET_TUNNELS;
+    return TOK_SMART_GW_OFFSET_RULES;
 }
 
 "SmartGatewayAllowNAT" {
index 80c0adf..c8f0ff5 100644 (file)
@@ -39,7 +39,9 @@
 /** structure that holds an interface name, mark and a pointer to the gateway that uses it */
 struct interfaceName {
   char name[IFNAMSIZ]; /**< interface name */
-  uint8_t mark; /**< marking */
+  uint8_t tableNr; /**< routing table number */
+  uint8_t ruleNr; /**< IP rule number */
+  uint8_t bypassRuleNr; /**< bypass IP rule number */
   struct gateway_entry *gw; /**< gateway that uses this interface name */
 };
 
@@ -262,41 +264,63 @@ static void set_unused_iptunnel_name(struct gateway_entry *gw) {
  * Run the multi-gateway script/
  *
  * @param mode the mode (see SCRIPT_MODE_* defines)
- * @param add true to add policy routing, false to remove it
+ * @param addMode true to add policy routing, false to remove it
  * @param ifname the interface name (optional)
- * @param ifmark the interface mark (optional
+ * @param tableNr the routing table number (optional)
+ * @param ruleNr the IP rule number/priority (optional)
+ * @param bypassRuleNr the bypass IP rule number/priority (optional)
  * @return true when successful
  */
-static bool multiGwRunScript(const char * mode, bool add, const char * ifname, uint8_t * ifmark) {
+static bool multiGwRunScript(const char * mode, bool addMode, const char * ifName, uint32_t tableNr, uint32_t ruleNr, uint32_t bypassRuleNr) {
   struct autobuf buf;
   int r;
 
+  assert(!strcmp(mode, SCRIPT_MODE_GENERIC) //
+      || !strcmp(mode, SCRIPT_MODE_OLSRIF)//
+      || !strcmp(mode, SCRIPT_MODE_SGWSRVTUN)//
+      || !strcmp(mode, SCRIPT_MODE_EGRESSIF)//
+      || !strcmp(mode, SCRIPT_MODE_SGWTUN)//
+      );
+
+  assert(strcmp(mode, SCRIPT_MODE_GENERIC) //
+      || (!strcmp(mode, SCRIPT_MODE_GENERIC) && !ifName && !tableNr && !ruleNr && !bypassRuleNr));
+
+  assert(strcmp(mode, SCRIPT_MODE_OLSRIF) //
+      || (!strcmp(mode, SCRIPT_MODE_OLSRIF) && ifName && !tableNr && !ruleNr && bypassRuleNr));
+
+  assert(strcmp(mode, SCRIPT_MODE_SGWSRVTUN) //
+      || (!strcmp(mode, SCRIPT_MODE_SGWSRVTUN) && ifName && tableNr&& ruleNr && !bypassRuleNr));
+
+  assert(strcmp(mode, SCRIPT_MODE_EGRESSIF) //
+      || (!strcmp(mode, SCRIPT_MODE_EGRESSIF) && ifName && tableNr && ruleNr && bypassRuleNr));
+
+  assert(strcmp(mode, SCRIPT_MODE_SGWTUN) //
+      || (!strcmp(mode, SCRIPT_MODE_SGWTUN) && ifName && tableNr && ruleNr && !bypassRuleNr));
+
   abuf_init(&buf, 1024);
 
   abuf_appendf(&buf, "\"%s\"", olsr_cnf->smart_gw_policyrouting_script);
 
   abuf_appendf(&buf, " \"%s\"", (olsr_cnf->ip_version == AF_INET) ? "ipv4" : "ipv6");
 
-  assert(!strcmp(mode, SCRIPT_MODE_GENERIC) || !strcmp(mode, SCRIPT_MODE_OLSRIF) ||
-      !strcmp(mode, SCRIPT_MODE_SGWSRVTUN) || !strcmp(mode, SCRIPT_MODE_EGRESSIF) ||
-      !strcmp(mode, SCRIPT_MODE_SGWTUN));
   abuf_appendf(&buf, " \"%s\"", mode);
 
-  abuf_appendf(&buf, " \"%s\"", add ? "add" : "del");
+  abuf_appendf(&buf, " \"%s\"", addMode ? "add" : "del");
 
-  if (ifname) {
-    assert(!strcmp(mode, SCRIPT_MODE_OLSRIF) || !strcmp(mode, SCRIPT_MODE_SGWSRVTUN) ||
-        !strcmp(mode, SCRIPT_MODE_EGRESSIF) || !strcmp(mode, SCRIPT_MODE_SGWTUN));
-    abuf_appendf(&buf, " \"%s\"", ifname);
-  } else {
-    assert(!strcmp(mode, SCRIPT_MODE_GENERIC));
+  if (ifName) {
+    abuf_appendf(&buf, " \"%s\"", ifName);
   }
-  if (ifmark) {
-    assert(!strcmp(mode, SCRIPT_MODE_SGWSRVTUN) || !strcmp(mode, SCRIPT_MODE_EGRESSIF) || !strcmp(mode, SCRIPT_MODE_SGWTUN));
-    assert(ifname);
-    abuf_appendf(&buf, " \"%u\"", *ifmark);
-  } else {
-    assert(!strcmp(mode, SCRIPT_MODE_GENERIC) || !strcmp(mode, SCRIPT_MODE_OLSRIF));
+
+  if (tableNr) {
+    abuf_appendf(&buf, " \"%u\"", tableNr);
+  }
+
+  if (ruleNr) {
+    abuf_appendf(&buf, " \"%u\"", ruleNr);
+  }
+
+  if (bypassRuleNr) {
+    abuf_appendf(&buf, " \"%u\"", bypassRuleNr);
   }
 
   r = system(buf.buf);
@@ -313,7 +337,7 @@ static bool multiGwRunScript(const char * mode, bool add, const char * ifname, u
  * @return true when successful
  */
 static bool multiGwRulesGeneric(bool add) {
-  return multiGwRunScript(SCRIPT_MODE_GENERIC, add, NULL, NULL);
+  return multiGwRunScript(SCRIPT_MODE_GENERIC, add, NULL, 0, 0, 0);
 }
 
 /**
@@ -324,10 +348,18 @@ static bool multiGwRulesGeneric(bool add) {
  */
 static bool multiGwRulesOlsrInterfaces(bool add) {
   bool ok = true;
-  struct interface * ifn;
+  struct olsr_if * ifn;
+  unsigned int i = 0;
 
-  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
-    if (!multiGwRunScript(SCRIPT_MODE_OLSRIF, add, ifn->int_name, NULL)) {
+  for (ifn = olsr_cnf->interfaces; ifn; ifn = ifn->next, i++) {
+    if (!multiGwRunScript( //
+        SCRIPT_MODE_OLSRIF,//
+        add, //
+        ifn->name, //
+        0, //
+        0, //
+        olsr_cnf->smart_gw_offset_rules + olsr_cnf->smart_gw_egress_interfaces_count + i //
+            )) {
       ok = false;
       if (add) {
         return ok;
@@ -345,7 +377,14 @@ static bool multiGwRulesOlsrInterfaces(bool add) {
  * @return true when successful
  */
 static bool multiGwRulesSgwServerTunnel(bool add) {
-  return multiGwRunScript(SCRIPT_MODE_SGWSRVTUN, add, server_tunnel_name(), &olsr_cnf->smart_gw_mark_offset_srvtun);
+  return multiGwRunScript( //
+      SCRIPT_MODE_SGWSRVTUN,//
+      add, //
+      server_tunnel_name(), //
+      olsr_cnf->smart_gw_offset_tables, //
+      olsr_cnf->smart_gw_offset_rules + olsr_cnf->smart_gw_egress_interfaces_count + getNrOfOlsrInterfaces(olsr_cnf), //
+      0 //
+      );
 }
 
 /**
@@ -360,7 +399,7 @@ static bool multiGwRulesEgressInterfaces(bool add) {
 
   for (i = 0; i < olsr_cnf->smart_gw_egress_interfaces_count; i++) {
     struct interfaceName * ifn = &sgwEgressInterfaceNames[i];
-    if (!multiGwRunScript(SCRIPT_MODE_EGRESSIF, add, ifn->name, &ifn->mark)) {
+    if (!multiGwRunScript(SCRIPT_MODE_EGRESSIF, add, ifn->name, ifn->tableNr, ifn->ruleNr, ifn->bypassRuleNr)) {
       ok = false;
       if (add) {
         return ok;
@@ -383,7 +422,7 @@ static bool multiGwRulesSgwTunnels(bool add) {
 
   while (i < olsr_cnf->smart_gw_use_count) {
     struct interfaceName * ifn = (olsr_cnf->ip_version == AF_INET) ? &sgwTunnel4InterfaceNames[i] : &sgwTunnel6InterfaceNames[i];
-    if (!multiGwRunScript(SCRIPT_MODE_SGWTUN, add, ifn->name, &ifn->mark)) {
+    if (!multiGwRunScript(SCRIPT_MODE_SGWTUN, add, ifn->name, ifn->tableNr, ifn->ruleNr, ifn->bypassRuleNr)) {
       ok = false;
       if (add) {
         return ok;
@@ -442,7 +481,7 @@ static void removeGatewayFromList(struct gw_list * gw_list, bool ipv4, struct gw
   if (gw->tunnel) {
     struct interfaceName * ifn = find_interfaceName(gw->gw);
     if (ifn) {
-      olsr_os_inetgw_tunnel_route(gw->tunnel->if_index, ipv4, false, ifn->mark);
+      olsr_os_inetgw_tunnel_route(gw->tunnel->if_index, ipv4, false, ifn->tableNr);
     }
     olsr_os_del_ipip_tunnel(gw->tunnel);
     set_unused_iptunnel_name(gw->gw);
@@ -543,6 +582,7 @@ int olsr_init_gateways(void) {
   } else {
     uint8_t i;
     struct sgw_egress_if * egressif;
+    unsigned int nrOlsrIfs = getNrOfOlsrInterfaces(olsr_cnf);
 
     /* setup the egress interface name/mark pairs */
     sgwEgressInterfaceNames = olsr_malloc(sizeof(struct interfaceName) * olsr_cnf->smart_gw_egress_interfaces_count, "sgwEgressInterfaceNames");
@@ -551,8 +591,9 @@ int olsr_init_gateways(void) {
     while (egressif) {
       struct interfaceName * ifn = &sgwEgressInterfaceNames[i];
       ifn->gw = NULL;
-      ifn->mark = i + olsr_cnf->smart_gw_mark_offset_egress;
-      egressif->mark = ifn->mark;
+      ifn->tableNr = olsr_cnf->smart_gw_offset_tables + 1 + i;
+      ifn->ruleNr = olsr_cnf->smart_gw_offset_rules + olsr_cnf->smart_gw_egress_interfaces_count + nrOlsrIfs + 1 + i;
+      ifn->bypassRuleNr = olsr_cnf->smart_gw_offset_rules + i;
       snprintf(&ifn->name[0], sizeof(ifn->name), "%s", egressif->name);
 
       egressif = egressif->next;
@@ -565,14 +606,21 @@ int olsr_init_gateways(void) {
     sgwTunnel6InterfaceNames = olsr_malloc(sizeof(struct interfaceName) * olsr_cnf->smart_gw_use_count, "sgwTunnel6InterfaceNames");
     for (i = 0; i < olsr_cnf->smart_gw_use_count; i++) {
       struct interfaceName * ifn = &sgwTunnel4InterfaceNames[i];
+      uint32_t tableNr = olsr_cnf->smart_gw_offset_tables + 1 + olsr_cnf->smart_gw_egress_interfaces_count + i;
+      uint32_t ruleNr = olsr_cnf->smart_gw_offset_rules + olsr_cnf->smart_gw_egress_interfaces_count + nrOlsrIfs + 1 + olsr_cnf->smart_gw_egress_interfaces_count + i;
+
       ifn->gw = NULL;
-      ifn->mark = i + olsr_cnf->smart_gw_mark_offset_tunnels;
-      snprintf(&ifn->name[0], sizeof(ifn->name), "tnl_4%03u", ifn->mark);
+      ifn->tableNr = tableNr;
+      ifn->ruleNr = ruleNr;
+      ifn->bypassRuleNr = 0;
+      snprintf(&ifn->name[0], sizeof(ifn->name), "tnl_4%03u", ifn->tableNr);
 
       ifn = &sgwTunnel6InterfaceNames[i];
       ifn->gw = NULL;
-      ifn->mark = i + olsr_cnf->smart_gw_mark_offset_tunnels;
-      snprintf(&ifn->name[0], sizeof(ifn->name), "tnl_6%03u", ifn->mark);
+      ifn->tableNr = tableNr;
+      ifn->ruleNr = ruleNr;
+      ifn->bypassRuleNr = 0;
+      snprintf(&ifn->name[0], sizeof(ifn->name), "tnl_6%03u", ifn->tableNr);
     }
   }
 
@@ -1000,7 +1048,7 @@ static void olsr_delete_gateway_tree_entry(struct gateway_entry * gw, uint8_t pr
         if (gw_in_list->tunnel) {
           struct interfaceName * ifn = find_interfaceName(gw_in_list->gw);
           if (ifn) {
-            olsr_os_inetgw_tunnel_route(gw_in_list->tunnel->if_index, true, false, ifn->mark);
+            olsr_os_inetgw_tunnel_route(gw_in_list->tunnel->if_index, true, false, ifn->tableNr);
           }
           olsr_os_del_ipip_tunnel(gw_in_list->tunnel);
           set_unused_iptunnel_name(gw_in_list->gw);
@@ -1022,7 +1070,7 @@ static void olsr_delete_gateway_tree_entry(struct gateway_entry * gw, uint8_t pr
         if (gw_in_list->tunnel) {
           struct interfaceName * ifn = find_interfaceName(gw_in_list->gw);
           if (ifn) {
-            olsr_os_inetgw_tunnel_route(gw_in_list->tunnel->if_index, false, false, ifn->mark);
+            olsr_os_inetgw_tunnel_route(gw_in_list->tunnel->if_index, false, false, ifn->tableNr);
           }
           olsr_os_del_ipip_tunnel(gw_in_list->tunnel);
           set_unused_iptunnel_name(gw_in_list->gw);
@@ -1135,7 +1183,7 @@ bool olsr_set_inet_gateway(struct gateway_entry * chosen_gw, bool ipv4, bool ipv
       new_v4gw_tunnel = olsr_os_add_ipip_tunnel(&new_gw->originator, true, name);
       if (new_v4gw_tunnel) {
         if (interfaceName) {
-          olsr_os_inetgw_tunnel_route(new_v4gw_tunnel->if_index, true, true, interfaceName->mark);
+          olsr_os_inetgw_tunnel_route(new_v4gw_tunnel->if_index, true, true, interfaceName->tableNr);
         }
         olsr_os_inetgw_tunnel_route(new_v4gw_tunnel->if_index, true, true, olsr_cnf->rt_table_tunnel);
 
@@ -1181,7 +1229,7 @@ bool olsr_set_inet_gateway(struct gateway_entry * chosen_gw, bool ipv4, bool ipv
       new_v6gw_tunnel = olsr_os_add_ipip_tunnel(&new_gw->originator, false, name);
       if (new_v6gw_tunnel) {
         if (interfaceName) {
-          olsr_os_inetgw_tunnel_route(new_v6gw_tunnel->if_index, false, true, interfaceName->mark);
+          olsr_os_inetgw_tunnel_route(new_v6gw_tunnel->if_index, false, true, interfaceName->tableNr);
         }
         olsr_os_inetgw_tunnel_route(new_v6gw_tunnel->if_index, false, true, olsr_cnf->rt_table_tunnel);
 
index fbe8302..19a1e5f 100644 (file)
 #define DEF_SMART_GW_ALWAYS_REMOVE_SERVER_TUNNEL  false
 #define DEF_GW_USE_COUNT     1
 #define DEF_GW_TAKEDOWN_PERCENTAGE 25
-#define DEF_GW_MARK_OFFSET_SRVTUN   90
-#define DEF_GW_MARK_OFFSET_EGRESS   91
-#define DEF_GW_MARK_OFFSET_TUNNELS 101
+#define DEF_GW_OFFSET_TABLES 90
+#define DEF_GW_OFFSET_RULES  0
 #define DEF_GW_PERIOD        10*1000
 #define DEF_GW_STABLE_COUNT  6
 #define DEF_GW_ALLOW_NAT     true
@@ -264,7 +263,6 @@ struct plugin_entry {
 
 struct sgw_egress_if {
   char *name;
-  uint8_t mark;
   struct sgw_egress_if *next;
 };
 
@@ -319,9 +317,8 @@ struct olsrd_config {
   char *smart_gw_policyrouting_script;
   struct sgw_egress_if * smart_gw_egress_interfaces;
   uint8_t smart_gw_egress_interfaces_count;
-  uint8_t smart_gw_mark_offset_srvtun;
-  uint8_t smart_gw_mark_offset_egress;
-  uint8_t smart_gw_mark_offset_tunnels;
+  uint32_t smart_gw_offset_tables;
+  uint32_t smart_gw_offset_rules;
   uint32_t smart_gw_period;
   uint8_t smart_gw_stablecount;
   uint8_t smart_gw_thresh;
@@ -379,6 +376,20 @@ extern "C" {
  * List functions
  */
 
+  /**
+   * Count the number of olsr interfaces
+   *
+   * @return the number of olsr interfaces
+   */
+  static inline unsigned int getNrOfOlsrInterfaces(struct olsrd_config * cfg) {
+    struct olsr_if * ifn;
+    unsigned int i = 0;
+
+      for (ifn = cfg->interfaces; ifn; ifn = ifn->next, i++) {}
+      return i;
+  }
+
+
   void ip_prefix_list_add(struct ip_prefix_list **, const union olsr_ip_addr *, uint8_t);
 
   int ip_prefix_list_remove(struct ip_prefix_list **, const union olsr_ip_addr *, uint8_t);