#!/bin/sh
(
  flock -n 200 || exit 1

  # Environment variable settings
  PATH=/usr/sbin:/sbin:/usr/bin:/bin
  export PATH

  LOGIN_TIME="$(date "+%Y-%m-%d_%H:%M:%S")"
  USERNAME="${PEERNAME}"
  PEERIP="${5}"

  USER_CONFIG="pppoe-user"
  USER_CFGID="$(uci show ${USER_CONFIG} | grep "${USERNAME}" | cut -d '.' -f 2)"

  # Convert Mbps to KBytes
  USER_QOS="$(uci get ${USER_CONFIG}.${USER_CFGID}.qos 2>/dev/null)"
  USER_UPLOAD="$(($(uci get ${USER_CONFIG}.${USER_CFGID}.urate 2>/dev/null) * 125))"
  USER_DOWNLOAD="$(($(uci get ${USER_CONFIG}.${USER_CFGID}.drate 2>/dev/null) * 125))"
  UPLOAD_BURST="$((USER_UPLOAD / 10))"
  DOWNLOAD_BURST="$((USER_DOWNLOAD / 10))"
  USER_CONNECT="$(uci get ${USER_CONFIG}.${USER_CFGID}.connect 2>/dev/null)"

  # Ensure that the obtained values are valid
  if [ -z "${USER_QOS}" ] || [ -z "${USER_UPLOAD}" ] || [ -z "${USER_DOWNLOAD}" ] || [ -z "${USER_CONNECT}" ]; then
      logger "${LOGIN_TIME} ERROR: Failed to get user config for (${USERNAME}) (${PEERIP})"
      exit 1
  fi

  UP="upload"
  DOWN="download"

  # Add traffic control rules
  if [ "${USER_QOS}" = "1" ]; then
      # Ensure rules are inserted in the correct order

      # Upload chain
      nft insert rule inet pppoe ${UP} ip saddr "${PEERIP}" ct count over "${USER_CONNECT}" drop
      nft insert rule inet pppoe ${UP} ip saddr "${PEERIP}" ct state new limit rate "${USER_CONNECT}"/minute accept
      nft insert rule inet pppoe ${UP} ip saddr "${PEERIP}" limit rate over "${USER_UPLOAD}" kbytes/second burst "${UPLOAD_BURST}" kbytes counter drop
      if [ $? -ne 0 ]; then
          logger "${LOGIN_TIME} ERROR: Failed to insert upload rules (${USERNAME}) (${PEERIP})"
          exit 1
      fi

      # Download chain
      nft insert rule inet pppoe ${DOWN} ip daddr "${PEERIP}" ct count over "${USER_CONNECT}" drop
      nft insert rule inet pppoe ${DOWN} ip daddr "${PEERIP}" ct state new limit rate "${USER_CONNECT}"/minute accept
      nft insert rule inet pppoe ${DOWN} ip daddr "${PEERIP}" limit rate over "${USER_DOWNLOAD}" kbytes/second burst "${DOWNLOAD_BURST}" kbytes counter drop
      if [ $? -ne 0 ]; then
          logger "${LOGIN_TIME} ERROR: Failed to insert download rules (${USERNAME}) (${PEERIP})"
          exit 1
      fi
  fi

  exit 0

) 200>/var/lock/ipup.lock
