#!/bin/bash
. /etc/kerbynet.conf
if [ "$DEBUG" = 0 ]; then
  ERROUT=/dev/null
else
  ERROUT="$DBGFILE"
fi
#
MASTERCONF="/etc/protonyx.conf"
# Load master.conf
. $MASTERCONF
#
CONFIG=$REGISTER/system/net/nb/Gateways
. $CONFPATH/notifications.conf
BACKUP_LEGS=`echo $BACKUP_LEGS|sed 's/,/ /g'`
function isBackup {
  THISG="$1"
  # Search in BACKUP_LEGS list
  # First convert GW to leg index
  if [ $THISG -ge 6 ]; then
    THISG=$(( $THISG - 1 ))
  fi
  for B in $BACKUP_LEGS; do
    if [ $B -eq $THISG ]; then
      echo 'yes'
      return
    fi
  done
  echo 'no'
}

cd $CONFIG
# Complete rewrite guys. iptables calls are slow so we need to minimize them.
# read once. add/remove rules as needed. How to compare?
# the CONNMARK --save-mark rule must be last. The order of the other rules doesn't matter
GW="$1"
CURRENTRULES=`iptables -t mangle -S NB_CT_POST|grep -v "^-N NB_CT_POST$"|sed "s/^-A NB_CT_POST //g"|sed 's/[[:space:]]*$//g'`
if [ -z "$GW" ] ; then
  # it means we need to review all rules
  GW=`ls -d ?? 2>>"$ERROUT"`
  # nooo we won't flush
  #  iptables -t mangle -F NB_CT_POST
  #iptables -t mangle -F NB_STAT
  for G in $GW ; do
    [ "$G" == 00 ] && continue
    # we need the rule if the G is enabled
    GWENABLED=`cat $G/Enabled 2>>"$ERROUT"`
    if [ ! "$GWENABLED" == yes ]; then
      GWISBACKUP=$(isBackup $G)
      if [ ! "$GWISBACKUP" == yes ]; then
        continue
      fi
    fi
    #[ `cat $G/Enabled 2>>"$ERROUT"` != yes ] && continue
    # let's build the rule we need
    printf -v HEXMARK "0x%x" "1$G"
    THERULE="-m realm --realm $HEXMARK -j MARK --set-xmark $HEXMARK/0xffffffff"
    NEWRULES="${NEWRULES}\n${THERULE}"
  done
  # regarding the final line...
  echo "$CURRENTRULES"|tail -1|grep -q -- "-j CONNMARK --save-mark"
  if [ $? -eq 0 ]; then
    # remove the last line
    CURRENTRULES=`echo "$CURRENTRULES"|sed '$ d'`
  else
    DOADDFINALRULE=yes
  fi
  
  # now we need to compare the rulesets. comm needs them sorted
  CURRENTRULESSORTED=`printf "%b" "$CURRENTRULES"|sort`
  NEWRULESSORTED=`printf "%b" "$NEWRULES"|sort`
  RULESTODELETE=`comm -23 <(echo "$CURRENTRULESSORTED") <(echo "$NEWRULESSORTED" )`
  RULESTOADD=`comm -13 <(echo "$CURRENTRULESSORTED") <(echo "$NEWRULESSORTED" )`
  # Common rules are already in place
  while read -r THERULE; do
    if [ -z "$THERULE" ]; then
      continue;
    fi
    CMD="iptables -t mangle -D NB_CT_POST $THERULE"
    #echo CMD="$CMD"
    $CMD
  done <<<"$RULESTODELETE"
  while read -r THERULE; do
    if [ -z "$THERULE" ]; then
      continue;
    fi
    CMD="iptables -t mangle -I NB_CT_POST 1 $THERULE"
    #echo CMD="$CMD"
    $CMD
  done <<<"$RULESTOADD"
  # do we need to add the final rule? Not if it existed in the first place
  if [ -n "$DOADDFINALRULE" ]; then
    CMD="iptables -t mangle -A NB_CT_POST -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff"
    #echo CMD="$CMD"
    $CMD
  fi
else
  # it means we only have to ensure the rule is correct for this GW only.
  # for single GWs we don't need to check the last rule
  # let's build the rule we need
  printf -v HEXMARK "0x%x" "1$GW"
  THERULE="-m realm --realm $HEXMARK -j MARK --set-xmark $HEXMARK/0xffffffff"
  # the double dash in grep separates grep's options from the search string
  echo "$CURRENTRULES"|grep -q -- "$THERULE";RULEEXISTS=$?
  MUSTADD=yes
  GWENABLED=`cat $G/Enabled 2>>"$ERROUT"`
  if [ ! "$GWENABLED" == yes ]; then
    GWISBACKUP=$(isBackup $G)
    if [ ! "$GWISBACKUP" == yes ]; then
      MUSTADD=no
    fi
  fi
  if [ "$MUSTADD" == yes ]; then
  #if [ `cat "$GW"/Enabled 2>>"$ERROUT"` == yes ]; then
    if [ $RULEEXISTS -ne 0 ]; then
      # rule does not exist we need to add it
      iptables -t mangle -I NB_CT_POST 1 $THERULE
    fi
  else
    if [ $RULEEXISTS -eq 0 ]; then
      # rule exists we need to delete it
      iptables -t mangle -D NB_CT_POST $THERULE
    fi
  fi
fi
