#!/bin/bash
# This script will set-up an example DS tree

#only set ENABLE_MPLS_IP to true if you installed the DSMPLS+IP patch
#ENABLE_MPLS_IP=false
ENABLE_MPLS_IP=true

IFACES="eth0"
TC=/usr/local/bin/tc

if test $# -gt 0
then
  case $1 in
  s|-s)
        if test $# -gt 1
        then
                if test $# -gt 2
                        then
                        case $3 in
                         BE)
                          echo BE statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 3 "red 4:"
                          ;;
                         EF)
                          echo EF statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 2 "pfifo 3:"
                          ;;
                         OR)
                          echo OR statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 2 "pfifo 9:"
                          ;;
                         AF1)
                          echo AF1 statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 8 "gred 5:"
                          ;;
                         AF2)
                          echo AF2 statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 8 "gred 6:"
                          ;;
                         AF3)
                          echo AF3 statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 8 "gred 7:"
                          ;;
                         *)
                          echo BE statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 3 "red 4:"
                          echo EF statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 2 "pfifo 3:"
                          echo OR statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 2 "pfifo 9:"
                          echo AF1 statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 8 "gred 5:"
                          echo AF2 statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 8 "gred 6:"
                          echo AF3 statistics on interface $2
                          $TC -s qdisc ls dev $2 | grep -A 8 "gred 7:"
                        esac
                else
			echo "***"$2"***"
                        $TC -s qdisc ls dev $2
                fi;
        else
                for i in $IFACES; do echo "***"$i"***"
                $TC -s qdisc ls dev $i 2>/dev/null; done
        fi;;
  d|-d)
        if test $# -gt 1
        then
                $TC qdisc del root dev $2 >/dev/null 2>/dev/null
        else
                for i in $IFACES; do
                $TC qdisc del root dev $i >/dev/null 2>/dev/null
                done
        fi;;
  h|-h|--help|-help)
        echo $0
        echo "     -s                   show statistics"
        echo "     -s interface         show statistics of interface"
        echo "     -s interface <PHB>   show PHB statistics on interface"
        echo "     -d                   delete filters and qdiscs"
        echo "                          install qdiscs and filers"
        echo "     <phb> = BE | EF | OR | AF1 | AF2 | AF3 | *"
  exit
  esac
else

if [ $ENABLE_MPLS_IP = true ]
then
  echo $0 running in MPLS + IP mode
  echo Make sure the kernel is patched with dsmpls+ip.patch
else
  echo $0 running in MPLS only mode
fi

for i in $IFACES; do

  echo
  echo Configuring interface $i

  if [ $ENABLE_MPLS_IP = true ]
  then
  $TC qdisc add dev $i root handle 1:0 dsmark indices 64 default_index 0x161 set_tc_index
  else
  $TC qdisc add dev $i root handle 1:0 dsmark indices 64 default_index 0x161
  fi

  $TC filter add dev $i parent 1:0 protocol all prio 1 tcindex mask 0xfc shift 2 pass_on

##### Set up of the proper qdisc on $i

# First a DSMARK qdisc is introduced in order to retrieve TOS from IP header

# Second a CBQ qdisc is used in order to support EF, AF and BE classes
$TC qdisc add dev $i parent 1:0 handle 2:0 cbq bandwidth 100Mbit cell 8 avpkt 1000 mpu 64
$TC filter add dev $i parent 2:0 protocol all prio 1 tcindex mask 0xf0 shift 4 pass_on

## Definition of the CBQ leaf classes to support AF, EF and BE
echo AF1
## AF Class 1 specific setup
$TC class add dev $i parent 2:0 classid 2:1 cbq bandwidth 100Mbit rate 15Mbit \
    avpkt 1000 prio 3 allot 1514 weight 1.5Mbit maxburst 21 defmap 0 borrow
$TC filter add dev $i parent 2:0 prio 1 handle 1 tcindex classid 2:1
$TC qdisc add dev $i handle 5:0 parent 2:1 gred setup DPs 3 default 2 grio
# --- AF Class 1 DP 1---
   $TC filter add dev $i parent 1:0 prio 1 handle 0x0a tcindex classid 1:111
   $TC qdisc change dev $i parent 2:1 gred limit 600KB min 150KB max 450KB burst 200 \
       avpkt 1000 bandwidth 100Mbit DP 1 probability 0.02 prio 2
# --- AF Class 1 DP 2---
   $TC filter add dev $i parent 1:0 prio 1 handle 0x0c tcindex classid 1:112
   $TC qdisc change dev $i parent 2:1 gred limit 600KB min 150KB max 450KB burst 200 \
       avpkt 1000 bandwidth 100Mbit DP 2 probability 0.04 prio 3

## AF Class 2 specific setup
echo AF2
$TC class add dev $i parent 2:0 classid 2:2 cbq bandwidth 100Mbit rate 15Mbit \
    avpkt 1000 prio 4 allot 1514 weight 1.5Mbit maxburst 21 defmap 0 borrow
$TC filter add dev $i parent 2:0 prio 1 handle 2 tcindex classid 2:2
$TC qdisc add dev $i handle 6:0 parent 2:2 gred setup DPs 3 default 2 grio
# --- AF Class 2 DP 1---
   $TC filter add dev $i parent 1:0 prio 1 handle 0x12 tcindex classid 1:121
   $TC qdisc change dev $i parent 2:2 gred limit 600KB min 150KB max 450KB burst 200 \
       avpkt 1000 bandwidth 100Mbit DP 1 probability 0.02 prio 2
# --- AF Class 2 DP 2---
   $TC filter add dev $i parent 1:0 prio 1 handle 0x14 tcindex classid 1:122
   $TC qdisc change dev $i parent 2:2 gred limit 600KB min 150KB max 450KB burst 200 \
       avpkt 1000 bandwidth 100Mbit DP 2 probability 0.04 prio 3

## AF Class 3 specific setup
echo AF3
$TC class add dev $i parent 2:0 classid 2:3 cbq bandwidth 100Mbit rate 15Mbit \
    avpkt 1000 prio 5 allot 1514 weight 1.5Mbit maxburst 21 defmap 0 borrow
$TC filter add dev $i parent 2:0 prio 1 handle 3 tcindex classid 2:3
$TC qdisc add dev $i handle 7:0 parent 2:3 gred setup DPs 3 default 2 grio
# --- AF Class 3 DP 1---
   $TC filter add dev $i parent 1:0 prio 1 handle 0x1a tcindex classid 1:131
   $TC qdisc change dev $i parent 2:3 gred limit 600KB min 150KB max 450KB burst 200 \
       avpkt 1000 bandwidth 100Mbit DP 1 probability 0.02 prio 2
# --- AF Class 3 DP 2---
   $TC filter add dev $i parent 1:0 prio 1 handle 0x1c tcindex classid 1:132
   $TC qdisc change dev $i parent 2:3 gred limit 600KB min 150KB max 450KB burst 200 \
       avpkt 1000 bandwidth 100Mbit DP 2 probability 0.04 prio 3

## EF class specific setup
echo EF
$TC class add dev $i parent 2:0 classid 2:5 cbq bandwidth 100Mbit rate 10Mbit \
    avpkt 1000 prio 2 bounded allot 1514 weight 1Mbit maxburst 10 defmap 0
$TC qdisc add dev $i handle 3:0 parent 2:5 pfifo limit 10
$TC filter add dev $i parent 1:0 prio 1 handle 0x2e tcindex classid 1:151
$TC filter add dev $i parent 2:0 prio 1 handle 5 tcindex classid 2:5

## BE class specific setup
echo BE
$TC class add dev $i parent 2:0 classid 2:6 cbq bandwidth 100Mbit rate 30Mbit \
    avpkt 1000 prio 7 allot 1514 weight 3Mbit maxburst 21 borrow
$TC qdisc add dev $i parent 2:6 handle 4:0 red limit 600KB min 150KB max 450KB burst 200 \
    avpkt 1000 bandwidth 100Mbit probability 0.4
#$TC filter add dev $i parent 1:0 prio 1 handle 0x0 tcindex classid 1:161
$TC filter add dev $i parent 2:0 prio 1 handle 6 tcindex classid 2:6

## OSPF - RSVP Pipe class specific setup
echo OSPF \& RSVP queue
$TC class add dev $i parent 2:0 classid 2:7 cbq bandwidth 100Mbit rate 1Mbit \
    avpkt 1000 prio 1 bounded allot 1514 weight 1Mbit maxburst 10 defmap 0
$TC qdisc add dev $i handle 9:0 parent 2:7 pfifo limit 10
$TC filter add dev $i parent 1:0 prio 1 handle 0x30 tcindex classid 1:171
$TC filter add dev $i parent 2:0 prio 1 handle 7 tcindex classid 2:7

done

fi
