#----------------------------------------------------------------
# 
# $Id: simple_ex.tcl,v 1.5 2002/01/14 05:31:28 geunkim Exp geunkim $
# Author : Geunhyung Kim
# Date   : 2002. 1. 4
# Note   : simple example of DiffServ
#
# Description : 
#       1 EF service : 1 Mbps (packet size: 128)
#       2 BE service : 9Mbps, 8 Mbps (packet size: 128)
#        
#---------------------------------------------------------------

set ns [new Simulator]

set ef [open ef_ex.tr w]
set bf1 [open bf_ex1.tr w]
set bf2 [open bf_ex2.tr w]

proc finish { } {
    global ef bf1 bf2 ns
    close $ef
    close $bf1
    close $bf2
    exec xgraph ef_ex.tr bf_ex1.tr bf_ex2.tr -geometry 800x400 &
    exit 0
}

set cir2 30000
set cbs2 1000

set cir4 1000000
set cbs4 3000

set ef_rate 4000000

set be1_rate 9000000
set be2_rate 8000000

set testTime 30.0

set ef_packetSize 128
set be_packetSize 128

set packetSize 1500

################################################################
# Set up the network topology


# Set nodes for simulation

# define nodes for EF service

set s1 [$ns node]
set s2 [$ns node]

set s3 [$ns node]
set s4 [$ns node]

set s5 [$ns node]
set s6 [$ns node]

# define the network nodes

set e1 [$ns node]
set e2 [$ns node]

set core [$ns node]

# Configuring the links

# Access Links

$ns duplex-link $s1 $e1 20Mb 0.1ms DropTail
$ns duplex-link $s2 $e2 20Mb 0.1ms DropTail

$ns duplex-link $s3 $e1 20Mb 0.1ms DropTail
$ns duplex-link $s4 $e2 20Mb 0.1ms DropTail

$ns duplex-link $s5 $e1 20Mb 0.1ms DropTail
$ns duplex-link $s6 $e2 20Mb 0.1ms DropTail

# Core Links

$ns simplex-link $e1 $core 10Mb 0.1ms dsRED/edge
$ns simplex-link $core $e1 10Mb 0.1ms dsRED/core
$ns simplex-link $core $e2 10Mb 0.1ms dsRED/core
$ns simplex-link $e2 $core 10Mb 0.1ms dsRED/edge
 
# Orientation of the links

$ns duplex-link-op $s1 $e1 orient up-right
$ns duplex-link-op $s3 $e1 orient down-right
$ns duplex-link-op $s5 $e1 orient right

$ns simplex-link-op $e1 $core orient right
$ns simplex-link-op $core $e1 orient left

$ns simplex-link-op $core $e2 orient right
$ns simplex-link-op $e2 $core orient left

$ns duplex-link-op $s2 $e2 orient up-left
$ns duplex-link-op $s4 $e2 orient down-left
$ns duplex-link-op $s6 $e2 orient left

# Positioning the Queues

$ns simplex-link-op $e1 $core queuePos 0.5
$ns simplex-link-op $core $e2 queuePos 0.5

$ns simplex-link-op $e2 $core queuePos 0.5
$ns simplex-link-op $core $e1 queuePos 0.5

# Queue handles for DiffServ network

set qE1C [[$ns link $e1 $core] queue]
set qCE1 [[$ns link $core $e1] queue]

set qE2C [[$ns link $e2 $core] queue]
set qCE2 [[$ns link $core $e2] queue]

################################################################
# Configuring the DiffServ Parameters

# For the DiffServ Cloud
# Set DS RED parameters for Edge1 to Core
#

# Set scheduring mode between queues
# Priority scheduring

$qE1C setSchedularMode PRI 

# Set the limit on the maximum bandwidth 
# puts a limit on the queue 0 bandwidth to 3 Mbps

$qE1C addQueueRate 0 3000000

# Set the number of physical queues

$qE1C set numQueues_ 2

# Set the number of virtual queue

$qE1C setNumPrec     2

# Set the mean packet size, which is used for RED calculations

$qE1C meanPktSize $packetSize

# Add entry to the Policy Table
# [source node ID] [destination node ID] policer type 

$qE1C addPolicyEntry [$s1 id] [$s2 id] TokenBucket 10 $cir2 $cbs2
$qE1C addPolicyEntry [$s3 id] [$s4 id] TokenBucket 20 $cir4 $cbs4
$qE1C addPolicyEntry [$s5 id] [$s6 id] TokenBucket 20 $cir4 $cbs4

# Add policer type and initial code point pair to the Policer table 

$qE1C addPolicerEntry TokenBucket 10 11
$qE1C addPolicerEntry TokenBucket 20 21

# Add an entry to the PHB Table 
# code point 10 is mapped to physical queue 0 and virtual 0
# code point 11 is mapped to physical queue 0 and virtual 1

$qE1C addPHBEntry 10 0 0
$qE1C addPHBEntry 11 0 1

$qE1C addPHBEntry 20 1 0
$qE1C addPHBEntry 21 1 1

# Set the RED papameters for each virtual queue

$qE1C configQ 0 0 45 45 0.9
$qE1C configQ 0 1 45 45 0.9

$qE1C configQ 1 0 10 10 0.9
$qE1C configQ 1 1 10 10 0.9

# Set DS RED parameters for Core to Edge1
#

$qCE1 setSchedularMode PRI
$qCE1 addQueueRate 0 3000000
$qCE1 meanPktSize $packetSize
$qCE1 set numQueues_ 2
$qCE1 setNumPrec 2
$qCE1 addPHBEntry 10 0 0
$qCE1 addPHBEntry 11 0 1

$qCE1 addPHBEntry 20 1 0
$qCE1 addPHBEntry 21 1 1

$qCE1 configQ 0 0 45 45 0.9
$qCE1 configQ 0 1 45 45 0.9

$qCE1 configQ 1 0 10 10 0.9
$qCE1 configQ 1 1 10 10 0.9

# Set DS RED parameters for Core to Edge2
#

$qCE2 setSchedularMode PRI
$qCE2 addQueueRate 0 3000000
$qCE2 meanPktSize $packetSize
$qCE2 set numQueues_ 2
$qCE2 setNumPrec 2
$qCE2 addPHBEntry 10 0 0
$qCE2 addPHBEntry 11 0 1

$qCE2 addPHBEntry 20 1 0
$qCE2 addPHBEntry 21 1 1

$qCE2 configQ 0 0 45 45 0.9
$qCE2 configQ 0 1 45 45 0.9

$qCE2 configQ 1 0 10 10 0.9
$qCE2 configQ 1 1 10 10 0.9

# Set DS RED parameters for Edge2 to Core
#

$qE2C setSchedularMode PRI
$qE2C addQueueRate 0 3000000
$qE2C meanPktSize $packetSize
$qE2C set numQueues_ 3
$qE2C setNumPrec 2
$qE2C addPolicyEntry [$s2 id] [$s1 id] TokenBucket 10 $cir2 $cbs2
$qE2C addPolicyEntry [$s3 id] [$s4 id] TokenBucket 20 $cir4 $cbs4
$qE2C addPolicyEntry [$s5 id] [$s6 id] TokenBucket 20 $cir4 $cbs4

$qE2C addPolicerEntry TokenBucket 10 11
$qE2C addPolicerEntry TokenBucket 20 21

$qE2C addPHBEntry 10 0 0
$qE2C addPHBEntry 11 0 1

$qE2C addPHBEntry 20 1 0
$qE2C addPHBEntry 21 1 1

$qE2C configQ 0 0 45 45 0.9
$qE2C configQ 0 1 45 45 0.9

$qE2C configQ 1 0 10 10 0.9
$qE2C configQ 1 1 10 10 0.9

#############################################################################
##
#
# Set up a CBR connection

set udp [new Agent/UDP]
$ns attach-agent $s1 $udp
set cbr1 [new Application/Traffic/CBR]
$cbr1 attach-agent $udp
$cbr1 set packet_size_ $ef_packetSize
$udp set packetSize_ $ef_packetSize
$cbr1 set rate_ $ef_rate
set null1 [new Agent/LossMonitor]
$ns attach-agent $s2 $null1
$ns connect $udp $null1

################################################################
#
# Set up a Best-Effort CBR connection 1
#

set udp1 [new Agent/UDP]
$ns attach-agent $s3 $udp1
set cbr2 [new Application/Traffic/CBR]
$cbr2 attach-agent $udp1
$cbr2 set packet_size_ $be_packetSize
$udp1 set packetSize_ $be_packetSize
$cbr2 set rate_ $be1_rate
set null2 [new Agent/LossMonitor]
$ns attach-agent $s4 $null2
$ns connect $udp1 $null2

################################################################
#
# Set up a Best-Effort CBR connection 2
#

set udp2 [new Agent/UDP]
$ns attach-agent $s5 $udp2
set cbr3 [new Application/Traffic/CBR]
$cbr3 attach-agent $udp2
$cbr3 set packet_size_ $be_packetSize
$udp2 set packetSize_ $be_packetSize
$cbr3 set rate_ $be2_rate
set null3 [new Agent/LossMonitor]
$ns attach-agent $s6 $null3
$ns connect $udp2 $null3

proc record { } {
    global null1 null2 null3 ef bf1 bf2
    set ns [Simulator instance]
    set time 0.5
    set bw1 [$null1 set bytes_]
    set bw2 [$null2 set bytes_]
    set bw3 [$null3 set bytes_]
    set now [$ns now]
    puts $ef "$now [expr $bw1/$time*8/1000000]"
    puts $bf1 "$now [expr $bw2/$time*8/1000000]"
    puts $bf2 "$now [expr $bw3/$time*8/1000000]"
    $null1 set bytes_ 0
    $null2 set bytes_ 0
    $null3 set bytes_ 0
    $ns at [expr $now+$time] "record"
}

$qE1C printPolicyTable
$qE1C printPolicerTable
$qE1C printPHBTable PRI

$qE2C printPolicyTable
$qE2C printPolicerTable
$qE2C printPHBTable PRI

$ns at 0.0 "record"

$ns at 0.0 "$cbr1 start"
$ns at 0.0 "$cbr2 start"
$ns at 0.0 "$cbr3 start"

$ns at 10.0 "$qE1C printStats"
$ns at 20.0 "$qE1C printStats"
$ns at 30.0 "$qE1C printStats"

$ns at $testTime "$cbr1 stop"
$ns at $testTime "$cbr2 stop"
$ns at $testTime "$cbr3 stop"

$ns at [expr $testTime + 1.0] "finish"

$ns run





