#!/bin/sh

# environment lte wmp for Fsmr3 specific qos iptables file

MIN=0
MAX=63
ETHIF=br0
Z3LINK="eth1+"
SFN_Z3_MASTER_IP="192.168.252.1"
SFN_SPLANE_DSCP=46
SFN_MPLANE_DSCP=18
SFN_IKE_DSCP=18
SFN_ICMP_DSCP=0

qos_validate_precondition() 
{
    # This function can be used for validating inputs  
    return 0;
}

qos_reset_chains() 
{
    $IPTABLES -t mangle -F POSTROUTING
    $IPTABLES -t mangle -Z POSTROUTING
    $IPTABLES -t mangle -F OUTPUT
    $IPTABLES -t mangle -Z OUTPUT
    $IPTABLES -t mangle -F FORWARD
    $IPTABLES -t mangle -Z FORWARD
    $IPTABLES -t mangle -F CHAIN_ICMP      2> /dev/null
    $IPTABLES -t mangle -Z CHAIN_ICMP      2> /dev/null
    $IPTABLES -t mangle -F CHAIN_IKE       2> /dev/null
    $IPTABLES -t mangle -Z CHAIN_IKE       2> /dev/null
    $IPTABLES -t mangle -F CHAIN_MPLANE    2> /dev/null
    $IPTABLES -t mangle -Z CHAIN_MPLANE    2> /dev/null
    $IPTABLES -t mangle -F CHAIN_SPLANE    2> /dev/null
    $IPTABLES -t mangle -Z CHAIN_SPLANE    2> /dev/null
    $IPTABLES -t mangle -F CHAIN_CPLANE    2> /dev/null
    $IPTABLES -t mangle -Z CHAIN_CPLANE    2> /dev/null
    $IPTABLES -t mangle -F CHAIN_CMPCRLSOURCE    2> /dev/null
    $IPTABLES -t mangle -Z CHAIN_CMPCRLSOURCE    2> /dev/null
    $IPTABLES -t mangle -F CHAIN_NTP_SYNC  2> /dev/null
    $IPTABLES -t mangle -Z CHAIN_NTP_SYNC  2> /dev/null

    # IP6 only
    if [ "$IPVERSION" = "6" ]; then
        $IPTABLES -t mangle -F CHAIN_NDP_MLD        2> /dev/null
        $IPTABLES -t mangle -Z CHAIN_NDP_MLD        2> /dev/null
        $IPTABLES -t mangle -F CHAIN_DSCP_ICMPv6    2> /dev/null
        $IPTABLES -t mangle -F CHAIN_DSCP_SCTP      2> /dev/null
        $IPTABLES -t mangle -Z CHAIN_DSCP_ICMPv6    2> /dev/null
        $IPTABLES -t mangle -Z CHAIN_DSCP_SCTP      2> /dev/null
    fi
    
    $IPTABLES -t mangle -P FORWARD ACCEPT
    $IPTABLES -t mangle -P OUTPUT  ACCEPT
}

start_qos() 
{
    qos_validate_precondition
    

    $IPTABLES -t mangle -N CHAIN_ICMP      2> /dev/null
    $IPTABLES -t mangle -N CHAIN_IKE       2> /dev/null
    $IPTABLES -t mangle -N CHAIN_MPLANE    2> /dev/null
    $IPTABLES -t mangle -N CHAIN_SPLANE    2> /dev/null
    $IPTABLES -t mangle -N CHAIN_CPLANE    2> /dev/null
    $IPTABLES -t mangle -N CHAIN_CMPCRLSOURCE    2> /dev/null
    $IPTABLES -t mangle -N CHAIN_NTP_SYNC  2> /dev/null

    if [ "$IPVERSION" = "6" ]; then
        $IPTABLES -t mangle -N CHAIN_NDP_MLD      2> /dev/null
        $IPTABLES -t mangle -N CHAIN_DSCP_ICMPv6  2> /dev/null
        $IPTABLES -t mangle -N CHAIN_DSCP_SCTP    2> /dev/null
    fi

    if [ -e "/tmp/iptables_addresses.conf" ]; then
        if [ -e "/tmp/iptables_qos.conf" ]; then

         
        #If MPlane IP & TRS IP are not defined return
            if [ "x$IP_MPLANE" = "x" -a "x$IP_PRIM_TRS" = "x" ]; then
                return 0;
            fi
            
            if [ "x$IP_MPLANE" != "x" -a "x$IP_MPLANE" != "x$IP_PRIM_TRS" ]; then
                IP_ADDRESS=$IP_MPLANE
            else 
                if [ "x$IP_MPLANE" = "x$IP_PRIM_TRS" -o "x$IP_MPLANE" = "x" ]; then
                    IP_ADDRESS=$IP_PRIM_TRS
                fi
            fi

            $IPTABLES -t mangle -A POSTROUTING -p udp -m multiport --sports 5001:5010 -j ACCEPT
            $IPTABLES -t mangle -A POSTROUTING -p udp -m multiport --dports 5001:5010 -j ACCEPT
            $IPTABLES -t mangle -A POSTROUTING -p udp --dport 2152 -j ACCEPT
            ######################################################
            #ICMP Traffic
            ######################################################
            #Review SSE rules before making changes here
            QOS_DSCP=`echo $TC_ICMPT  | awk -F "," '{print $1}'`
            QOS_VPRI=`echo $TC_ICMPT  | awk -F "," '{print $3}'`

            # NDP/MLD are IPv6 only
            if [ "$IPVERSION" = "6" ]; then
                QOS_DSCP_NDP_MLD=`echo $TC_NDP_MLD | awk -F "," '{print $1}'`
                QOS_VPRI_NDP_MLD=`echo $TC_NDP_MLD | awk -F "," '{print $3}'`
            fi

            QOS_DSCP_SSE=`echo $TC_SSE  | awk -F "," '{print $1}'`
            QOS_PHB_SSE=`echo $TC_SSE  | awk -F "," '{print $2}'`
            QOS_VPRI_SSE=`echo $TC_SSE  | awk -F "," '{print $3}'`
            QOS_VID_SSE=`echo $TC_SSE  | awk -F "," '{print $4}'`
            #ICMP packet from SSE device will also encounter this rule. But this rule will prevent SSE DSCP to be altered.
            #It will not consider packet with source as BTS subnet & dscp value = DSCP_SSE
         

# RJa: different handling in IPv4/IPv6 case

        if [ "$IPVERSION" = "4" ]; then 
            if [ ! -z "$IP_FTM_BTS_SUBNET_ADR" ]; then

                if [ "$QOS_PHB_SSE" != "255" ]; then

                        $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ ! -s $IP_FTM_BTS_SUBNET_ADR/$FTM_BTS_SUBNET_MASK -p icmp  -j CHAIN_ICMP
                        $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -s $IP_FTM_BTS_SUBNET_ADR/$FTM_BTS_SUBNET_MASK -j DSCP --set-dscp $QOS_DSCP_SSE
                        $IPTABLES -t mangle -A POSTROUTING -s $IP_FTM_BTS_SUBNET_ADR/$FTM_BTS_SUBNET_MASK -j CLASSIFY --set-class 0:$QOS_VPRI_SSE
                else
                        $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ ! -s $IP_FTM_BTS_SUBNET_ADR/$FTM_BTS_SUBNET_MASK -p icmp  -j CHAIN_ICMP
                fi

            else
                        $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmp -j CHAIN_ICMP
            fi

            if [ -e "/tmp/isSfnMaster" ]; then
                $IPTABLES -t mangle -A POSTROUTING -o ${Z3LINK} -p icmp -j CHAIN_ICMP
            fi
            $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmpv6 -j CHAIN_ICMP

        else # IPv6 case
                # ICMPv6 subset NDP,MLD redirected to separate chain
                # NDP
                $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmpv6 -m icmp6 --icmpv6-type 135 -j CHAIN_NDP_MLD
                $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmpv6 -m icmp6 --icmpv6-type 136 -j CHAIN_NDP_MLD

                # MLD
                $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmpv6 -m icmp6 --icmpv6-type 130 -j CHAIN_NDP_MLD
                $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmpv6 -m icmp6 --icmpv6-type 131 -j CHAIN_NDP_MLD
                $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmpv6 -m icmp6 --icmpv6-type 132 -j CHAIN_NDP_MLD

                # MLDv2
                $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmpv6 -m icmp6 --icmpv6-type 143 -j CHAIN_NDP_MLD

                # "normal" icmp traffic
                $IPTABLES -t mangle -A POSTROUTING -o ${ETHIF}+ -p icmpv6 -j CHAIN_ICMP

                # In case IPv6 Ipsec over IPv4
                $IPTABLES -t mangle -A OUTPUT  -p icmpv6 -j CHAIN_DSCP_ICMPv6
            fi



# Temporary check to avoid error messages on console (--icmp-type currently not available in ip6tables)
# -> either remove check as soon as kernel support for icmpv6 is available
# -> or extend with appropriate IPv6 case

            if [ -e "/tmp/isSfnMaster" ]; then
                $IPTABLES -t mangle -A CHAIN_ICMP -o ${Z3LINK} -j DSCP --set-dscp $SFN_ICMP_DSCP
                $IPTABLES -t mangle -A CHAIN_ICMP -o ${Z3LINK} -j ACCEPT
            fi

            if [ "$IPVERSION" = "4" ]; then
                $IPTABLES -t mangle -A CHAIN_ICMP -p icmp --icmp-type echo-reply -j ACCEPT
            else
                #Bypass ICMPv6 replies - type 129
                $IPTABLES -t mangle -A CHAIN_ICMP -p icmpv6 --icmpv6-type 129 -j ACCEPT
            fi

            if [ "$IPVERSION" = "6" ]; then
                # ICMPv6 subset NDP/MLD
                $IPTABLES -t mangle -A CHAIN_NDP_MLD -j CLASSIFY --set-class 0:$QOS_VPRI_NDP_MLD
                $IPTABLES -t mangle -A CHAIN_NDP_MLD -j DSCP --set-dscp $QOS_DSCP_NDP_MLD
                $IPTABLES -t mangle -A CHAIN_NDP_MLD -j ACCEPT

                #Bypass ICMPv6 replies - type 129
                $IPTABLES -t mangle -A CHAIN_DSCP_ICMPv6 -p icmpv6 --icmpv6-type 129 -j ACCEPT
            fi

            $IPTABLES -t mangle -A CHAIN_ICMP -j CLASSIFY --set-class 0:$QOS_VPRI
            $IPTABLES -t mangle -A CHAIN_ICMP -j DSCP --set-dscp $QOS_DSCP
            $IPTABLES -t mangle -A CHAIN_ICMP -j ACCEPT

                #Bypass bfd traffic since dscp is set in stack itself
                $IPTABLES -t mangle -A POSTROUTING -p udp -m multiport --dports 3784,4784 -j ACCEPT
                
                ######################################################
                #IKE Traffic Protocol UDP && port 500
                ######################################################
                QOS_DSCP=`echo $TC_IKE  | awk -F "," '{print $1}'`
                QOS_VPRI=`echo $TC_IKE  | awk -F "," '{print $3}'`
                
                $IPTABLES -t mangle -A POSTROUTING -p udp --dport 500 -j CHAIN_IKE
                if [ -e "/tmp/isSfnMaster" ]; then
                    $IPTABLES -t mangle -A CHAIN_IKE -o ${Z3LINK} -j DSCP --set-dscp $SFN_IKE_DSCP
                    $IPTABLES -t mangle -A CHAIN_IKE -o ${Z3LINK} -j ACCEPT
                fi
                $IPTABLES -t mangle -A CHAIN_IKE -j DSCP --set-dscp $QOS_DSCP
                $IPTABLES -t mangle -A CHAIN_IKE -j CLASSIFY --set-class 0:$QOS_VPRI
                $IPTABLES -t mangle -A CHAIN_IKE -j ACCEPT
  
                
                ######################################################
                #CONTROL PLANE Traffic - C-Plane IP && protocol SCTP
                ######################################################
                    QOS_DSCP=`echo $TC_C_PLANE  | awk -F "," '{print $1}'`
                    QOS_VPRI=`echo $TC_C_PLANE  | awk -F "," '{print $3}'`
                    
                    $IPTABLES -t mangle -A POSTROUTING -p sctp -j CHAIN_CPLANE

                    if [ -e "/tmp/isFZAP" ]; then 
                        $IPTABLES -t mangle -A POSTROUTING -p udp --sport 16009 -j CHAIN_CPLANE
                    fi

                    #IGMP Packets shall be treated as C-plane packets
                    $IPTABLES -t mangle -A POSTROUTING -d 224/4 -p igmp -j CHAIN_CPLANE

                    $IPTABLES -t mangle -A CHAIN_CPLANE -j DSCP --set-dscp $QOS_DSCP
                    $IPTABLES -t mangle -A CHAIN_CPLANE -j CLASSIFY --set-class 0:$QOS_VPRI
                    #$IPTABLES -t mangle -A CHAIN_CPLANE -m dscp --dscp $QOS_DSCP -j CLASSIFY --set-class 0:$QOS_DSCP
                    $IPTABLES -t mangle -A CHAIN_CPLANE -j ACCEPT

                    if [ "$IPVERSION" = "6" ]; then
                        #CPLANE In case IPv6 Ipsec over IPv4
                        $IPTABLES -t mangle -A OUTPUT  -p sctp -j CHAIN_DSCP_SCTP
                        $IPTABLES -t mangle -A CHAIN_DSCP_SCTP -j DSCP --set-dscp $QOS_DSCP
                    fi

                ######################################################
                #SYNCHONIZATION PLANE Traffic
                ######################################################
                QOS_DSCP=`echo $TC_S_PLANE  | awk -F "," '{print $1}'`
                QOS_VPRI=`echo $TC_S_PLANE  | awk -F "," '{print $3}'`
                if [ "x$IP_SPLANE" != "x" ]; then
                    QOS_DSCP=`echo $TC_S_PLANE  | awk -F "," '{print $1}'`
                    QOS_VPRI=`echo $TC_S_PLANE  | awk -F "," '{print $3}'`

# Temporary check to avoid error messages on console (S-Plane IP address is currently IPv4-only)
# -> TODO:  extend with appropriate IPv6 case
                    if [ "$IPVERSION" = "4" ] && is_ipv4_addr "$IP_SPLANE"
                    then

                        $IPTABLES -t mangle -A POSTROUTING -s $IP_SPLANE -p udp -m multiport --dport 319,320 -j CHAIN_SPLANE
                        if [ -e "/tmp/isSfnMaster" ]; then
                            $IPTABLES -t mangle -A POSTROUTING -o ${Z3LINK} -s $SFN_Z3_MASTER_IP -p udp -m multiport --dport 319,320 -j CHAIN_SPLANE
                        fi

                        if [ -e "/tmp/isSfnMaster" ]; then
                            $IPTABLES -t mangle -A CHAIN_SPLANE -o ${Z3LINK} -j DSCP --set-dscp $SFN_SPLANE_DSCP
                            $IPTABLES -t mangle -A CHAIN_SPLANE -o ${Z3LINK} -j ACCEPT
                        fi
                    elif [ "$IPVERSION" = "6" ] && [ "$IP_SPLANE" != "::" ]
                    then
                         $IPTABLES -t mangle -A POSTROUTING -s $IP_SPLANE -p udp -m multiport --dport 319,320 -j CHAIN_SPLANE
                    fi
                    $IPTABLES -t mangle -A CHAIN_SPLANE -j DSCP --set-dscp $QOS_DSCP
                    $IPTABLES -t mangle -A CHAIN_SPLANE -j CLASSIFY --set-class 0:$QOS_VPRI
                    $IPTABLES -t mangle -A CHAIN_SPLANE -j ACCEPT

fi # end temporary check

                ######################################################
                           # NTP SYNC Traffic
                ######################################################

                if [ "$IPVERSION" = "4" ];then

                   if [ "x$IP_NTP_SYNC_CLIENT1" != "x" ]; then

                      $IPTABLES -t mangle -A POSTROUTING  -s $IP_NTP_SYNC_CLIENT1 -p udp --sport 123 --dport 123  -j CHAIN_NTP_SYNC

                      $IPTABLES -t mangle -A CHAIN_NTP_SYNC -j DSCP --set-dscp $QOS_DSCP
                      $IPTABLES -t mangle -A CHAIN_NTP_SYNC -j CLASSIFY --set-class 0:$QOS_VPRI
                      $IPTABLES -t mangle -A CHAIN_NTP_SYNC -j ACCEPT
                   fi

                fi #end NTP rules

                ######################################################
                #MANAGEMENT PLANE Traffic
                ######################################################

                #PR 109937ESPE01 fix:

                QOS_DSCP=`echo $TC_M_PLANE  | awk -F "," '{print $1}'`
                QOS_VPRI=`echo $TC_M_PLANE  | awk -F "," '{print $3}'`

# Temporary check to avoid error messages on console (M-Plane IP address is currently IPv4-only)
# -> TODO:  extend with appropriate IPv6 case
if [ "$IPVERSION" = "4" ] && is_ipv4_addr "$IP_ADDRESS"
then

            $IPTABLES -t mangle -A POSTROUTING -s $IP_ADDRESS -j CHAIN_MPLANE
            if [ -e "/tmp/isSfnMaster" ]; then
                $IPTABLES -t mangle -A POSTROUTING -o ${Z3LINK} -s $SFN_Z3_MASTER_IP -j CHAIN_MPLANE
            fi

            $IPTABLES -t mangle -A POSTROUTING -p udp -m multiport --dport 53 -j CHAIN_MPLANE
            $IPTABLES -t mangle -A POSTROUTING -p tcp --dport 53 -j CHAIN_MPLANE

#PR 43254ESPE07: FZM50 :IPSec : DSCP value is not copied to outer IP header for User Plane in case of collapsed application IPs
            $IPTABLES -t mangle -I CHAIN_MPLANE 1 -p esp -j ACCEPT
            if [ -e "/tmp/isSfnMaster" ]; then
                $IPTABLES -t mangle -A CHAIN_MPLANE -o ${Z3LINK} -j DSCP --set-dscp $SFN_MPLANE_DSCP
                $IPTABLES -t mangle -A CHAIN_MPLANE -o ${Z3LINK} -j ACCEPT
            fi
            $IPTABLES -t mangle -A CHAIN_MPLANE -j DSCP --set-dscp $QOS_DSCP
            if [ -e "/tmp/iptables_rsyslog.conf" ]; then
                . /tmp/iptables_rsyslog.conf
                    $IPTABLES -t mangle -A POSTROUTING -p udp  --dport $PORT -j CHAIN_MPLANE
                    $IPTABLES -t mangle -A POSTROUTING -p tcp  --dport $PORT -j CHAIN_MPLANE
                    $IPTABLES -t mangle -A CHAIN_MPLANE -d $IP_ADDR -p tcp --dport $PORT -j DSCP --set-dscp $DSCP_VALUE
                    $IPTABLES -t mangle -A CHAIN_MPLANE -d $IP_ADDR -p udp --dport $PORT -j DSCP --set-dscp $DSCP_VALUE
            fi
            $IPTABLES -t mangle -A CHAIN_MPLANE -j CLASSIFY --set-class 0:$QOS_VPRI

            $IPTABLES -t mangle -A CHAIN_MPLANE -j ACCEPT

fi # end temporary check

if [ "$IPVERSION" = "6" ]; then
    $IP6TABLES -t mangle -A POSTROUTING -s $IP_ADDRESS -j CHAIN_MPLANE
    $IP6TABLES -t mangle -A POSTROUTING -p udp -m multiport --dport 123,53 -j CHAIN_MPLANE
    $IP6TABLES -t mangle -A POSTROUTING -p tcp --dport 53 -j CHAIN_MPLANE
    QOS_TOS=$((QOS_DSCP*4))
    $IP6TABLES -t mangle -A CHAIN_MPLANE -j TOS --set-tos $QOS_TOS
    if [ -e "/tmp/iptables_rsyslog.conf" ]; then
       . /tmp/iptables_rsyslog.conf
           TOS_VALUE=$(($DSCP_VALUE*4))
            $IP6TABLES -t mangle -A POSTROUTING -p udp  --dport $PORT -j CHAIN_MPLANE
            $IP6TABLES -t mangle -A POSTROUTING -p tcp  --dport $PORT -j CHAIN_MPLANE
            $IP6TABLES -t mangle -A CHAIN_MPLANE -d $IP_ADDR -p tcp --dport $PORT -j TOS --set-tos $TOS_VALUE
            $IP6TABLES -t mangle -A CHAIN_MPLANE -d $IP_ADDR -p udp --dport $PORT -j TOS --set-tos $TOS_VALUE
    fi
    $IP6TABLES -t mangle -A CHAIN_MPLANE -j ACCEPT
fi

        ######################################################
        #SRC_CMP_CRL PLANE Traffic
        ######################################################
        QOS_DSCP=`echo $TC_M_PLANE  | awk -F "," '{print $1}'`
        # Temporary check to avoid error messages on console (srcCmpCrl IP address is currently IPv4-only)
        # -> TODO:  extend with appropriate IPv6 case
        if [ "$IPVERSION" = "4" ] && is_ipv4_addr "$IP_CMP_CRL_SOURCE_IP_ADDR"
        then

            $IPTABLES -t mangle -A POSTROUTING -p tcp -s $IP_CMP_CRL_SOURCE_IP_ADDR -j CHAIN_CMPCRLSOURCE
            $IPTABLES -t mangle -A CHAIN_CMPCRLSOURCE -j DSCP --set-dscp $QOS_DSCP
        fi # end temporary check
	if [ "$IPVERSION" = "6" ]; then
            QOS_TOS=$((QOS_DSCP*4))
	    $IP6TABLES -t mangle -A POSTROUTING -p tcp -s $IP_CMP_CRL_SOURCE_IP_ADDR -j CHAIN_CMPCRLSOURCE
            $IP6TABLES -t mangle -A CHAIN_CMPCRLSOURCE -j TOS --set-tos $QOS_TOS
	fi

    fi #/tmp/iptables_qos.conf
fi #/tmp/iptables_addresses.conf
}

stop_qos() 
{
    qos_reset_chains
}

status_qos() 
{
    echo "======================================================================"
    echo "                       mangle - table"
    echo "======================================================================"
    $IPTABLES -v -L -n -t mangle --line-numbers
}
