#!/bin/sh set -x [ -z "$IF_RT" ] && exit 0 [ -z "$IF_RT_GW" ] && exit 0 if [ "$MODE" = "start" ]; then # Creates the VRF if not present in /etc/iproute2/rt_tables grep -qEi "$IF_RT[ ]*$IFACE" /etc/iproute2/rt_tables \ || /bin/echo -e "$IF_RT\t$IFACE" >> /etc/iproute2/rt_tables # Add the default route (rt-gw) in the VRF if not present ip route show table $IF_RT | grep -qEi "default via $IF_RT_GW" \ || ip route add default via $IF_RT_GW table $IF_RT # Creates a rule to ensure that packets marked with rt-fwmark are routed accordingly for fwmark in $IF_RT_FWMARK; do pref=$(( 10000 + `/bin/echo -e "ibase=16\n${fwmark##0x}\n" | bc` )) ip rule show | grep -qEi "$pref:.*from all fwmark $fwmark lookup $IFACE" \ || ip rule add from all fwmark $fwmark lookup $IFACE pref $pref # Ensure that the mangle table correctly marks new connections incoming on the interface if ! iptables -L -nv -t mangle | grep -q 'CONNMARK.*'$IFACE'.*'$IF_ADDRESS'.*state NEW CONNMARK set.*'$IF_RT_FWMARK; then iptables -t mangle -A PREROUTING -i $IFACE -d $IF_ADDRESS -m state --state NEW -j CONNMARK --set-mark $IF_RT_FWMARK fi # Put specified users in the correct table for username in $IF_RT_LOCALUSER; do usernameid=`id -u $username` if ! iptables -L OUTPUT -nv -t mangle | \ grep -q 'MARK.*owner UID match '$usernameid' MARK set.*'$IF_RT_FWMARK ; then iptables -t mangle -A OUTPUT -m owner --uid $username -j MARK --set-mark $IF_RT_FWMARK fi done # Ensure that the mangle table correctly restore the mark for packets from existing connections if ! iptables -L -nv -t mangle | grep -q 'CONNMARK.*eth+.*CONNMARK restore'; then iptables -t mangle -A PREROUTING -i eth+ -j CONNMARK --restore-mark fi done # for each address listed as rt-oa on the interface, add a rule to say that this source IP # should be routed on the correct VRF - especially useful when using DSR/Service Loopbacks # or VIPs created by heartbeat. for addr in $IF_ADDRESS $IF_RT_OA; do pref=$(( 20000 + `/bin/echo -e "ibase=16\n${IF_RT_FWMARK##0x}\n" | bc` )) ip rule show | grep -qEi "$pref:.*from $addr lookup $IFACE" \ || ip rule add from $addr table $IF_RT pref $pref done # Imports global route table into VRF table ( if [ ! -z "$IF_RT_IMPORTGLOBAL" ]; then if [ ! -z "$IF_RT_IMPORTFILTER" ]; then for f in $IF_RT_IMPORTFILTER; do ip route show | grep -Ei "$f" done else ip route show fi fi ) | sed -e 's/$/ table '$IF_RT'/g' -e 's/^/ip route add /g' \ | sh || true elif [ "$MODE" = "stop" ]; then for addr in $IF_ADDRESS $IF_RT_OA; do ip rule show | grep -qEi "from $addr lookup $IFACE" \ && ip rule del from $addr lookup $IFACE done for fwmark in $IF_RT_FWMARK; do ip rule show | grep -qEi "from all fwmark $fwmark lookup $IFACE" \ || ip rule del from all fwmark $fwmark lookup $IFACE if iptables -L -nv -t mangle | grep -q 'CONNMARK.*'$IFACE'.*'$IF_ADDRESS'.*state NEW CONNMARK set.*'$IF_RT_FWMARK; then iptables -t mangle -D PREROUTING -i $IFACE -d $IF_ADDRESS -m state --state NEW -j CONNMARK --set-mark $IF_RT_FWMARK fi for username in $IF_RT_LOCALUSER; do usernameid=`id -u $username` if iptables -L OUTPUT -nv -t mangle | \ grep -q 'MARK.*owner UID match '$usernameid' MARK set.*'$IF_RT_FWMARK ; then iptables -t mangle -D OUTPUT -m owner --uid $username -j MARK --set-mark $IF_RT_FWMARK fi done done ip route show table $IF_RT | grep -qEi "default via $IF_RT_GW" \ && ip route del default via $IF_RT_GW table $IF_RT grep -v "$IF_RT[ ]*$IFACE" /etc/iproute2/rt_tables \ > /etc/iproute2/rt_tables.tmp mv /etc/iproute2/rt_tables.tmp /etc/iproute2/rt_tables fi