Dynamic gateways and more
authorJean-Michel Nirgal Vourgère <jmv@nirgal.com>
Tue, 19 Jul 2016 10:40:54 +0000 (10:40 +0000)
committerJean-Michel Nirgal Vourgère <jmv@nirgal.com>
Tue, 19 Jul 2016 10:40:54 +0000 (10:40 +0000)
Stop using $LOGICAL
Gateway argument is now optionnal
Log commands only if VERBOSITY=1
Copyrights -> GPLv3

source-route

index 8485750..b8410d8 100755 (executable)
@@ -1,49 +1,59 @@
 #!/bin/sh
+# ip source routing ifupdown script
+# (C) 2015 Nirgal Vourgère
+# GPL-3+
+#
 # This script set up source routing for a given interface
-# Argument $1: The gateway
+# Optionnal argument $1: The gateway. If missing, the interface gateway is required.
 # Example usage: In /etc/network/interfaces
 # iface eth7 inet static
 #     address 192.168.5.42/24
-#     /root/source-route-via-v4 192.168.1.15
+#     post-up source-route 192.168.1.1
+# or
+# iface eth7 inet static
+#     address 192.168.5.42/24
+#     gateway 192.168.5.1
+#     post-up source-route
 
 #set -x 
-iface=$LOGICAL
-rttable=from$LOGICAL
-LOGGER="logger -t source-route-via"
+RTTABLE=from$IFACE
+LOGGER="logger -t source-route"
 
-$LOGGER -- IFACE=$IFACE LOGICAL=$LOGICAL ADDRFAM=$ADDRFAM METHOD=$METHOD MODE=$MODE PHASE=$PHASE VERBOSITY=$VERBOSITY PATH=$PATH
+if test "$VERBOSITY" = 1
+then
+       echo " IFACE=$IFACE LOGICAL=$LOGICAL ADDRFAM=$ADDRFAM METHOD=$METHOD MODE=$MODE PHASE=$PHASE VERBOSITY=$VERBOSITY PATH=$PATH" >&2
+       $LOGGER -- IFACE=$IFACE LOGICAL=$LOGICAL ADDRFAM=$ADDRFAM METHOD=$METHOD MODE=$MODE PHASE=$PHASE VERBOSITY=$VERBOSITY PATH=$PATH
+fi
 
+critical_log() {
+       $LOGGER -- "$@"
+       echo "$@" >&2
+}
 if ! which ipv4calc >/dev/null
 then
-    echo ipv4calc not found: apt-get install libnetwork-ipv4addr-perl >&2
+    critical_log "ipv4calc not found: apt-get install libnetwork-ipv4addr-perl"
     exit 2
 fi
 if ! which ipv6calc >/dev/null
 then
-    echo ipv6calc not found: apt-get install ipv6calc >&2
+    critical_log "ipv6calc not found: apt-get install ipv6calc"
     exit 2
 fi
-if test -z "$LOGICAL"
+if test -z "$IFACE"
 then
-   echo \$LOGICAL var is empty. >&2
+   critical_log "\$IFACE var is empty. Are you really running from /etc/network/interfaces ?"
    exit 2
 fi
 if test "$PHASE" != "post-up"
 then
-   echo $0 is only valid in "post-up". >&2
-   exit 2
-fi
-if test -z "$1"
-then
-   echo Missing gateway parameter. >&2
+   critical_log "Invalid \$PHASE. $0 is only valid in 'post-up'."
    exit 2
 fi
 
 RT_TABLES=/etc/iproute2/rt_tables
-if ! grep -q $rttable /etc/iproute2/rt_tables
+if ! grep -q $RTTABLE /etc/iproute2/rt_tables
 then
-       $LOGGER $RT_TABLES does not have $rttable entry.
-       echo $RT_TABLES does not have $rttable entry. >&2
+       critical_log "$RT_TABLES does not have $RTTABLE entry."
        exit 2
 fi
 
@@ -55,36 +65,51 @@ inet6)
        IPFLAG=-6
        ;;
 *)
-       $LOGGER \$ADDRFAM must be inet or inet6. Ignoring.
+       echo \$ADDRFAM must be inet or inet6. Ignoring. >&2
        exit 0
        ;;
 esac
-IPADDR=$(ip $IPFLAG -o addr show $LOGICAL | grep -w $ADDRFAM | grep global | sed -re "s/.*$ADDRFAM (.*)\/.*/\1/")
-IPCIDR=$(ip -o addr show $LOGICAL | grep -w $ADDRFAM | grep global | sed -re "s/.*$ADDRFAM .*\/([^ ]*).*/\1/")
+IPADDR=$(ip $IPFLAG -o addr show $IFACE | grep -w $ADDRFAM | grep global | sed -re "s/.*$ADDRFAM (.*)\/.*/\1/")
+IPCIDR=$(ip $IPFLAG -o addr show $IFACE | grep -w $ADDRFAM | grep global | sed -re "s/.*$ADDRFAM .*\/([^ ]*).*/\1/")
 if test "$ADDRFAM" = "inet6"
 then
        IPNET=$(ipv6calc --in ipv6 --out ipv6 --maskprefix $IPADDR/$IPCIDR)
 else
        IPNET=$(ipv4calc --network $IPADDR/$IPCIDR)/$IPCIDR
 fi
-echo IP address: $IPADDR >&2
-echo CIDR: $IPCIDR >&2
-echo Network: $IPNET >&2
+if test -n "$1"
+then
+       IPGW=$1
+else
+       IPGW=$(ip $IPFLAG -o route show | grep default | sed -re "s/.*via ([^ ]*) .*/\1/")
+fi
+if test -z "$IPGW"
+then
+   critical_log "Could not find the gateway."
+   exit 2
+fi
+
+# Setting up source routing on $IFACE, so that packets from $IFACE don't get answered on another interface
+echo "Setting up source routing on $IFACE: from $IPADDR -> route $IPNET via $IPGW" >&2
+$LOGGER -- "Setting up source routing on $IFACE: from $IPADDR -> route $IPNET via $IPGW"
 
-# Setting up source routing on $iface, so that packets from $iface don't get answered on another interface
-if ! ip $IPFLAG route show table $rttable | grep -q default  # Once only
+if ! ip $IPFLAG route show table $RTTABLE | grep -q default  # Once only
 then
-        $LOGGER Setting up default gateway on iproute2 table $rttable
-        $LOGGER -- ip $IPFLAG route add $IPNET dev "$iface" scope link table $rttable
-        ip $IPFLAG route add $IPNET dev "$iface" scope link table $rttable
-        $LOGGER -- ip $IPFLAG route add default via "$1" dev "$iface" table $rttable
-        ip $IPFLAG route add default via "$1" dev "$iface" table $rttable
+       if test "$VERBOSITY" = 1
+       then
+               $LOGGER -- ip $IPFLAG route add $IPNET dev "$IFACE" scope link table $RTTABLE
+               $LOGGER -- ip $IPFLAG route add default via "$IPGW" dev "$IFACE" table $RTTABLE
+       fi
+        ip $IPFLAG route add $IPNET dev "$IFACE" scope link table $RTTABLE
+        ip $IPFLAG route add default via "$IPGW" dev "$IFACE" table $RTTABLE
 fi
-if ! ip $IPFLAG rule show | grep -q $rttable  # Once only
+if ! ip $IPFLAG rule show | grep -q $RTTABLE  # Once only
 then
-        $LOGGER Setting up source routing on "$iface" from $IPADDR
-        $LOGGER -- ip $IPFLAG rule add from $IPADDR table $rttable
-        ip $IPFLAG rule add from $IPADDR table $rttable
+       if test "$VERBOSITY" = 1
+       then
+               $LOGGER -- ip $IPFLAG rule add from $IPADDR table $RTTABLE
+       fi
+        ip $IPFLAG rule add from $IPADDR table $RTTABLE
 fi
 
 ip $IPFLAG route flush cache