Diffserv Framework in J-Sim

December 22, 2003

In this document, we discuss how we implement the differentiated service (Diffserv) classes in J-Sim.  As mentioned in [1][2][3][4], in the differentiated service architecture, the source of a connection specifies the service class it desires and a service profile that characterizes the traffic the source will send in the specified class. The architecture then achieves service differentiation by (1) implementing classification and conditioning functions at network edge routers and (ii) applying the per-hop behaviors at core routers to traffic aggregates that have been appropriately marked by edge routers. 

There are two major components: (1) the tagging/policing mechanisms at the edge routers that appropriately mark or police packets before they enter the network; and (2) the active queue management mechanisms at the core routers that buffer and forward packets and realize the per-hop behavior. The drcl.diffserv package is built on top of the INET framework and implements the various classes that may serve as the building blocks for Diffserv, and includes markers/taggers, service profile, policers/shapers and queue management algorithms. Also, a hierarchical queue scheduling (HQS) structure is included to facilitate flexible configuration of queues, queue management algorithms and scheduling algorithms (e.g. round robin, priority queue etc.)  The following table lists the available components/classes that can be used to construct core and edge routers.

Core Components

HQS
TrafficConditioner

Classes

DFProfile
Meter
   TB_Meter
   TC_Meter
   TSW_Meter
Marker
HQS
   Priority Queue
   Weighted Round Robin

In what follows, we introduce the drcl.diffserv package in the following sequence.  Following a formal description of Diffserv components,  we also give two step-by-step examples to illustrate their use. 


1 The Framework

The figures in this section give a conceptual view of the partial, internal structure of  edge and core routers.  By partial, we mean the structure that is relevant to our Diffserv framework.  For the complete nodal structure, please refer to the section of Default CSL Decomposition in the INET document.

1.1 Diffserv Codepoint (DSCP) and INET ToS

The bits (in the ToS field) that are currently used in J-Sim/INET for differentiated services are:

 

8

7

6

5

4

3

2

1

0

Un-used

 

 

 

 

 

 

CE

 

ECT

Data/Control

We use bits 3-8 as the differentiated service codepoint (DSCP) in the format of cccddd, where ccc specifies the class and ddd specifies the drop preference. 

 

Binary

Octet

EF

111111

077

AF11

001010

012

AF12

001100

014

AF13

001110

016

AF21

010010

022

AF22

010100

024

AF23

010110

026

AF31

011010

032

AF32

011100

034

AF33

011110

036

BE

000000

000

The interested readers are referred to  RFC 2474  for a detailed account of DSCP. Other than defining the DSCPs.

1.2 Edge Router/TrafficConditioner

Figure 1: The internal structure of a TrafficConditioner in the core service layer (csl) of an edge router.


TrafficConditioner is the core component that realizes the differentiated services at the edge router (also possible to include a traffic conditioner at an end host).  A TrafficConditioner contains a set of DFProfiles.  Each DFProfile defines a service level agreement (SLA) and is uniquely identified by a six-tuple (source, destination, DSCP, source_mask, destination_mask, DSCP_mask),.  When a packet arrives at a TrafficConditioner, the packet is classified to find the DFProfile to which it belongs, and then is passed to the profile for further processing.

Specifically, TrafficConditioner defines the following methods:

 void addProfile(long src_, DFProfile dfp_)
           
 void addProfile(long src_, long dest_, DFProfile dfp_)
           
 void addProfile(long src_, long dest_, long dscp_, DFProfile dfp_)
           
 void addProfile(long src_, long srcmask_, long dest_, long destmask_, long dscp_, long dscpmask_, DFProfile dfp_)
           
 DFProfile getProfile(long src_, long dest_, long dscp_)
           
 void removeProfile(DFProfile dfp_)
           
 void removeProfile(long src_, long dest_, long dscp_)
           

Each profile contains a meter and a marker.  A meter measures whether or not the traffic source has been sending packets in compliance with the profile. In the current implementation, we have implemented the token bucket (TB_meter), the three color meter (TC_meter) and the time sliding window meter (TSW_meter). A marker may operate in several modes (packet tagging/dropping, with or without considering existing differentiated service codepoints (DSCP)) and determines how packets are treated based on the meter results. The possible operation modes of a marker are listed below:

Table I: Marker modes and operations.

Marker Mode

Tagger

POLICER

DROPPER

BY_PASS

SET_EF

SET_AF11

COLOR_AWARE

COLOR_BLIND

Operation

set to EF

set to AF11

set DSCP according to both the existing DSCP and the result of meter

set DSCP according to the result of meter

drop out-of-
profile packets

drop packets uncondi-
tionally

no operation

For example, if the marker is used as a tagger in the color aware mode, then the differentiated service codepoint (DSCP) in the header of each packet will be set according to both the existing DSCP and the result returned by the meter.

1.3 Core Router/HQS

Figure 2: An example of a HQS in the core service layer (csl) of a core router.


At the heart of the core router is the hierarchical queue set (HQS) component. HQS is a subclass of drcl.inet.core.Queue, the base class for implementing a buffer/buffer management and/or a scheduling algorithm.

HQS is hierarchical in the sense that in a HQS are embeded a set of queues (drcl.inet.core.Queue), any of which may be another HQS.  For example, the above figure shows a typical HQS for the Diffserv architecture, where there are three top classes, EF (expedite forwarding), BE (best efforts) and AF (assure forwarding). Packets of different classes are scheduled by an (inter-class) scheduler such as priority queue or weighted round robin (WRR).  The AF queue is another HQS which is further divided into three sub-queues, AF1x, AF2x, and AF3x. These sub-queues may be governed by, for example, three instances of RED.  A different (intra-class) scheduler in the AF queue is used to schedule packets among these AF sub-queues.

A sub-queue in a HQS is associated with a (ClassID, ClassIDMask) identifier. When a packet arrives at a HQS, the packet is classified and enqueued to the corresponding sub-queue.  If the sub-queue is another HQS, then the process repeats.  In our framework, the packet is classified by its ToS field in the packet header.  The two-tuple identifier of the corresponding sub-queue has the longest match to the ToS field of the packet.

Specifically, HQS defines the following fields and methods:

protected  long classIDMask
           
protected  Map qs
           
 void addQueueSet(drcl.inet.core.Queue child_, long classMask, long classId)
           
protected  java.lang.String configInfo(java.lang.String prefix_)
          Prints the configuration information of this HQS.
protected  java.lang.String configInfo(java.lang.String prefix_, drcl.inet.core.Queue q_)
          Prints out the configuration information associated with the child queue.
 java.lang.Object dequeue()
          Dequeues and returns the first object in the queue.
 java.lang.Object enqueue(java.lang.Object obj_)
          Enqueues the object at the end of the queue
 java.lang.Object firstElement()
          Retrieves but not dequeue the first object in the queue.
 int getCapacity()
          Returns the capacity of the queue.
 long getClassIDMask()
           
 drcl.inet.core.Queue getQueueSet(long classID)
           
 int getSize()
          Returns the current size of the queue.
 boolean isEmpty()
          Return true if the queue is empty.
 boolean isFull()
          Return true if the queue is full.
protected abstract  drcl.inet.core.Queue pickEligibleQueue()
          This method is called when this HQS needs to pick a child queue to perform dequeue operation.
 void removeQueueSet(drcl.inet.core.Queue leaf_)
           
 void setClassIDMask(long mask_)
           

A HQS subclass must implement its scheduling algorithm by overriding the pickEligibleQueue() method to choose a sub-queue for the dequeue operation.

2 Classes and Components

2.1 DFConstants

DFConstants collects the constants that are used in our Diffserv framework.  In particular, it defines the constants of codepoints and their corresponding values in the ToS field of an INET packet header (see the section of Diffserv Codepoint (DSCP) and INET ToS for details), and possible label values and some operation mode constants.

Specifically, DFConstants defines the following constants:

static int EF
          The DSCP of the EF class.
static int BE
          The DSCP of the BE (Best-Efforts) class.
static int AF11
          The DSCP of the AF11 class.
static int AF12
          The DSCP of the AF12 class.
static int AF13
          The DSCP of the AF13 class.
static int AF21
          The DSCP of the AF21 class.
static int AF22
          The DSCP of the AF22 class.
static int AF23
          The DSCP of the AF23 class.
static int AF31
          The DSCP of the AF31 class.
static int AF32
          The DSCP of the AF32 class.
static int AF33
          The DSCP of the AF33 class.
static int AF1x
          The DSCP of the AF1x class.
static int AF2x
          The DSCP of the AF2x class.
static int AF3x
          The DSCP of the AF3x class.
static long EF_TOS
          The INET ToS of the EF class.
static long BE_TOS
          The INET ToS of the BE class.
static long AF11_TOS
          The INET ToS of the AF11 class.
static long AF12_TOS
          The INET ToS of the AF12 class.
static long AF13_TOS
          The INET ToS of the AF13 class.
static long AF21_TOS
          The INET ToS of the AF21 class.
static long AF22_TOS
          The INET ToS of the AF22 class.
static long AF23_TOS
          The INET ToS of the AF23 class.
static long AF31_TOS
          The INET ToS of the AF31 class.
static long AF32_TOS
          The INET ToS of the AF32 class.
static long AF33_TOS
          The INET ToS of the AF33 class.
static long AF1x_TOS
          The INET ToS of the AF1x class.
static long AF2x_TOS
          The INET ToS of the AF2x class.
static long AF3x_TOS
          The INET ToS of the AF3x class.
static long DFCLASS_MASK
          The INET ToS mask to distinguish AF1x, AF2x, AF3x, EF and BE packets.
static long DSCPMask
          Mask for masking out DSCP in INET ToS
static int DSCPShift
          Bit shift of DSCP in INET ToS
static int GREEN
          The GREEN value of the three-label AF class.
static int YELLOW
          The YELLOW value of the three-label AF class.
static int RED
          The RED value of the three-label AF class.
static int IN_PROFILE
          The IN_PROFILE value of the two-label AF class.
static int OUT_PROFILE
          The OUT_PROFILE value of the two-label AF class.
static java.lang.String SINGLE_RATE
          The "single rate" mode of a meter.
static java.lang.String TWO_RATE
          The "two rate" mode of a meter.

 

2.2 DFProfile

DFProfile defines a service level agreement (SLA).  Each profile contains a meter and a marker that specify the treatment of each packet. The meter/marker can be added to a profile using setMarker(Marker m_) and setMeter(Meter m_).  Specifically, DFProfile defines the following methods:

 void duplicate(java.lang.Object source_)
          Duplicates the marker and meter from source_.
 Marker getMarker()
          Returns the installed marker.
 Meter getMeter()
          Returns the installed meter.
 java.lang.String info(java.lang.String prefix_)
          Prints out the content of the installed marker and meter.
 void reset()
          Resets the installed marker and meter.
 void set(Marker marker_, Meter meter_)
          Intalls the marker and meter to this profile.
 void setMarker(Marker m_)
          Intalls the marker to this profile.
 void setMeter(Meter m_)
          Intalls the meter to this profile.

2.3 Meter and Subclasses

A Meter updates, upon packet arrival, the statistics (e.g., the average sending rate) and keeps track of whether the traffic source has been sending packets in compliance with the SLA installed.  Specifically, Meter defines the following methods:

abstract  void duplicate(Object source_)
          Copies the content of source_ to this meter.
abstract  java.lang.String info(java.lang.String prefix_)
          Prints out the content of this meter.
protected abstract  int measure(Packet p, double now_)
          Returns the label for the packet based on the measurement and
the agreement of the connection the packet belongs to.
abstract  void reset()
          Resets this meter to be used anew.

A Meter subclass should override all the above four methods.  In particular, the measure() method is called, when a packet arrives, to update the statistics and returns a label that indicates how the source behaves compared to the installed SLA with the arriving packet.

In the current release, we have implemented the following meters:

Meter Class

Parameters

Label returned 
by measure()

Note

TB_meter

burst (bucket) size
token generation rate

DFConstants.OUT_PROFILE
DFConstants.IN_PROFILE

 

TSW_meter

target rate
window length

DFConstants.OUT_PROFILE
DFConstants.IN_PROFILE

 

TC_meter

CBS (Committed Burst Size)
CIR (Committed Information Rate)
PBS (Peak Burst Size)
PIR (Peak Information Rate)

DFConstants.GREEN
DFConstants.YELLOW
DFConstants.RED

TC_Meter can be in the single or two-rate mode 

2.4 Marker

Marker is a do-it-all class for packet tagging/policing.  It can operate in different modes by specifying the operation mode.  Valid operation modes and the corresponding operations are listed in the following table:

Marker Mode

Tagger

POLICER

DROPPER

BY_PASS

SET_EF

SET_AF11

COLOR_AWARE

COLOR_BLIND

Operation

set DSCP to EF

set DSCP to AF11

set DSCP according to both the existing DSCP and the packet's label.

set DSCP according to the packet's label.

drop out-of-
profile (not GREEN or IN_PROFILE) packets

drop packets uncondi-
tionally

no operation

Specifically, Marker defines the following fields and methods:

static java.lang.String BY_PASS
           
static java.lang.String COLOR_AWARE
           
static java.lang.String COLOR_BLIND
           
static java.lang.String DROPPER
           
static java.lang.String POLICER
           
static java.lang.String SET_AF11
           
static java.lang.String SET_EF
 void duplicate(java.lang.Object source_)
         Copies the content of the source_ object to this object.
 java.lang.String getMode()
         Returns the operation mode of this marker.
 java.lang.String info()
         Prints out the content of this marker.
 java.lang.String info(java.lang.String prefix_)
         Prints out the content of this marker. 
protected  boolean markPacket(InetPacket p_, int label)
          Marks in the DSCP part of ToS in the packet header with the packet's label.
 void reset()
          Resets this marker.
 void setMode(java.lang.String mode_)
          Sets the operation mode of this marker.

2.5 Scheduler and Queue Managements

In the current release, we include in J-Sim two HQS implementations (see HQS specification for details of implementing a HQS): priority queue (pq) and weighted round robin (wrr). The pq class defines the following methods to add a child queue with a priority:

 void addQueueSet(drcl.inet.core.Queue child_, long classMask_, long classId_)
          Adds the child queue with the same priority as (the currently lowest priority in this HQS + 1).
 void addQueueSet(drcl.inet.core.Queue child_, long classMask_, long classId_, int priority_)
          Adds the child queue with the specified priority.

 The wrr class defines the following methods to add a child queue with a weight:

 void addQueueSet(drcl.inet.core.Queue child_, long classMask_, long classId_)
           
 void addQueueSet(drcl.inet.core.Queue child_, long classMask_, long classId_, int weight_)
           

In addition to HQS, we implement a new queue class (drcl.inet.core.Queue) called ColorQueueColorQueue is a 3-color queue, an extension of RIO.  Specifically, the class defines the following method to configure a ColorQueue:

 void config(double minth_green, double maxth_green, double imaxp_green, double minth_yellow, double maxth_yellow, double imaxp_yellow, double minth_red, double maxth_red, double imaxp_red, double qw, double bandwidth, int meanPacketSize)
           

Parameters:

  • (minth_green, maxth_green): the minimum and maximum threshold of the green queue.
  • (minth_yellow, maxth_yellow): the minimum and maximum threshold of the yellow queue.
  • (minth_red, maxth_red): the minimum and maximum threshold of the red queue.
  • imaxp_green, imaxp_yellow, imaxp_red: the reciprocal of maximum dropping probability.
  • qw: weight for calculating the average queue length.
  • bandwidth: bandwidth of the link, for calculating the "packet time constant" (maximum number of packets that can be placed on the link.
  • manPacketSize: for calculating the "packet time constant".

4 Examples

In this section, we use two examples to illustrate how to compose simulation scenarios with the Diffserv components and classes described in this document. We demonstrate that service differentiation can be achieved among EF and AF flows with different target rates.  We assume that readers have browsed through and understand the four examples in the INET Tutorial.

Example 1

In this example, we construct the scenario that consists of four hosts (with random traffic sources), two edge routers and one core router

Figure 3: The scenario to be constructed in Example 1.


Step 0. Defining constants:

set bandwidth 1.5e6; # bps
set propDelay 0.5; # second

Step 1. Creating the network topology

Step 1.1. We create a component directory to hold all the components created in this example:

cd [mkdir -q drcl.comp.Component /test]

Step 1.2.  We create the network topology and assign node addresses:

# Create topology
puts "create topology..."
set link_ [java::new drcl.inet.Link]
$link_ setPropDelay $propDelay
set adjMatrix_ [java::new {int[][]} 7 {{1 2} {0 3 4} {0 5 6} {1} {1} {2} {2}}]
java::call drcl.inet.InetUtil createTopology [! .] $adjMatrix_ $link_

Step 2. Setting up the traffic parameters for sources at h3 and h4.

We set up the traffic parameters for sources at hosts h3 and h4 with the packet size 1000 bytes, the packet inter-arrival times 0.01s and 0.02s (the packet sending rate is 0.4Mbps and 0.8Mbps,) respectively.

puts "Setting up traffic parameters"
# Traffic parameters: minPktSize, maxPktSize, minInterPktInterval, maxInterPktInterval
# the last parameter in random() is the time when the source begins to generate packets based on random parameters.
set random(3) "1000 1000 0.02 0.02 10.0"
set random(4) "1000 1000 0.01 0.01 10.0"
# in addition, generate packets at fixed time points (at time 0.0)
set timepoints(3) [java::new {double[]} 1 "0.0"]
set timepoints(4) [java::new {double[]} 1 "0.0"]

Step 3. Building the nodal structure.

We set up the edge/core routers and the end hosts.

puts "Create builders..."
# CSLBuilder:
set ccb [mkdir drcl.inet.core.CSLBuilder .coreCSLBuilder]
mkdir drcl.diffserv.scheduling.pq $ccb/q1; # only at interface 1
set ecb [mkdir drcl.inet.core.CSLBuilder .edgeCSLBuilder]
mkdir drcl.diffserv.TrafficConditioner $ecb/pf0_0; # only at interface 0
# NodeBuilder:
set nb [mkdir drcl.inet.NodeBuilder .nodeBuilder]
$nb setBandwidth $bandwidth

puts "build..."
$nb build [! n0] $ccb
$nb build [! n1] $ecb
$nb build [! n2,h?]
! n0 setBandwidth 1 [expr $bandwidth/2]
# traffic generators
set port_ 100
foreach i {3 4} {
eval [subst -nocommands {set traffic($i) [java::new drcl.net.traffic.traffic_FixedPoints $random($i) $timepoints($i)]}]
set dest_ [expr $i+2]
java::call drcl.inet.InetUtil createTrafficSource $traffic($i) "source" [! h$i] [! h$dest_] 0 $port_
}

The internal structures of the end hosts are shown in Figure 4. The source/sink is connected to an up port (of port ID 100) of the core service layer (csl).

Figure 4: The internal structure of end hosts h3, h4 (left) and h5, h6 (right) in Example 1.


The internal structures of the core service layers (csl) of the edge and core routers are shown in Figure 5 and 6 respectively. In particular, the interface 0 of the edge router n1 is configured with a traffic conditioner, and the interface 1 of the core router n0 is configured with a priority HQS.

Figure 5: The internal structure of the core service layer (csl) of the edge router n1 in Example 1.

          

Figure 6: The internal structure of the core service layer (csl) of the core router n0 in Example 1.


Step 4. Setting up static routes.

We set up the static routes between h3 and h5 and between h4 and h6.

puts "Set up static routes..."
java::call drcl.inet.InetUtil setupRoutes [! h3] [! h5]
java::call drcl.inet.InetUtil setupRoutes [! h4] [! h6]

Step 5. Setting up a Plotter component to view results online.

We set up a TrafficMonitor component and a Plotter component to on-line keep track of  the instantaneous throughput.  For details regarding the usages of TrafficMonitor and Plotter , please refer to TrafficMonitor/TrafficMonitor2 in the NET document and x,y-plot -- drcl.comp.tool.Plotter in the INET document.

puts "Traffic monitor & plotter..."
mkdir drcl.comp.Component .monitor
set plot_ [mkdir drcl.comp.tool.Plotter .monitor/plot]
set tms_ {EF_src AF_src EF_dest AF_dest}
set targets_ {h3/source/down@ h4/source/down@ n2/1@ n2/2@}
for {set i 0} {$i < [llength $tms_]} {incr i} {
set tm_ [lindex $tms_ $i]
set tm($i) [mkdir drcl.net.tool.TrafficMonitor2 .monitor/$tm_]
$tm($i) setOutputInterval 0.1
$tm($i) setWindowSize 2.0
connect -c [lindex $targets_ $i] -to $tm($i)/in@
connect -c $tm($i)/bytecount@ -to $plot_/$i@0
}

In the above script, we count the data bytes sent at the down port of source at h3 (EF source), sent at the down port of source at h4 (AF source), sent at interface 1 of router n2 (EF destination), and sent at interface 2 of router n2 (AF destination), respectively.   The output interval and the size of the measurement window in the traffic monitor have been set to 0.1 and 2.0, respectively.

Step 6. Configuring the edge router.

We configure the traffic conditioner at the edge router n1.

puts "Setting up TC"
proc ConfigProfile {meterType markerType source trafficConditioner} {
if [string match "Meter" $meterType] {
set meter [java::null]
} else {
set meter [java::new drcl.diffserv.$meterType]
}
set profile [java::new drcl.diffserv.DFProfile]
$profile set [java::new drcl.diffserv.Marker $markerType] $meter
! $trafficConditioner addProfile [! $source getDefaultAddress] $profile
return $profile
}

ConfigProfile "Meter" "SET_EF" h3 n1/csl/pf0_0
ConfigProfile "Meter" "SET_AF11" h4 n1/csl/pf0_0

In the above script, we create two profiles, each of which has a meter (drcl.diffserv.Meter) and a marker (drcl.diffserv.Marker). The marker is set to mode "SET_EF" and "SET_AF11" in profiler0 and profiler1, respectively. Hence, the traffic conditioner will mark packets from host h3 as EF and those from host h4 as AF11. 

Step 7. Configuring the core router.

We configure the HQS at core router n0.

puts "Setting up HQS"
set bs_queue [java::new drcl.inet.core.queue.DropTail "bs_q"]
set af1x_queue [java::new drcl.inet.core.queue.DropTail "af1x_q"]
set ef_queue [java::new drcl.inet.core.queue.DropTail "ef_q"]
$bs_queue setCapacity 4000
$af1x_queue setCapacity 4000
$ef_queue setCapacity 4000

! n0/csl/q1 setClassIDMask [java::field drcl.diffserv.DFConstants DSCPMask]
! n0/csl/q1 addQueueSet $ef_queue 0xffff [java::field drcl.diffserv.DFConstants EF_TOS]
! n0/csl/q1 addQueueSet $af1x_queue 0xfff8 [java::field drcl.diffserv.DFConstants AF11_TOS]
! n0/csl/q1 addQueueSet $bs_queue 0xffff [java::field drcl.diffserv.DFConstants BE_TOS]

In the above script, we setup a BE queue, an AF1x queue, and an EF queue and add them to the HQS, q1, of router n0 using the method addQueueSet() in the HQS class . Two points are in order:

  • If the upper level HQS is a priority queue, the order in which a sub-queue is added determines its priority. For example, in the above script, ef_queue, af1x_queue and bs_queue are in the descending order pf priority.  If the upper level HQS is weighted round robin, the weight of each queue is set using the setWeight() method.
  • ClassMask for af1x_q is set to 0xfff8 in "! n0/csl/q1 addQueueSet $af1x_queue 0xfff8 [java::field drcl.diffserv.DFConstants AF11_TOS]" so that all packets in the classes of AF11, AF12, AF13 will be enqueued into the af1x_q queue (longest march).

Step 8. Starting the simulation.

For details of simulation runtime and simulation control, please refer to the sections of Runtime, Simulation Engine and Simulation Control and rt, run/stop/resume, reset, reboot in the INET document.

puts "Attach simulator runtime..."
set sim [attach_simulator .]

# start the traffic source and run the simulation for 20 second
puts "Simulation starts..."
run h3-4
$sim stopAt 20

Result 

After executing the above script, one window pops up and displays on the fly the instantaneous bytes sent by the EF/AF sources and received by the EF/AF receivers (Figure 7).  These parameters are continuously updated. We can observe that although the AF sources send packets at a rate (0.8Mbps) twice as large as  EF sources do (0.4Mbps), the EF flow sustain reasonable throughput (when it competes with the AF source for the bottleneck bandwidth 0.75Mbps).  This is due to the use of priority queue. 

Figure 7: The simulation result of Example 1.     

 

The source code of this example is available here.

In summary, we have shown in this example:

  1. How to add traffic sources to end hosts.
  2. How to set up profiles and traffic conditioners at edge routers.
  3. How to set up the HQS structures at the core router.

Example 2

In this example, we construct a more complicated scenario, where each host is configured with a traffic conditioner to pre-mark packets. Each edge route uses a traffic conditioner for packet re-marking and traffic shaping. The core router is configured with a priority HQS and a three-color queue for AF traffic. Two TCP connections are established using the AF1x service and compete for the bottleneck link bandwidth of 1Mps with an EF traffic which is profiled to send at 0.125Mbps.  

Figure 8:  The scenario to be constructed in Example 2.


Step 0. Defining constants.

set bandwidth 1.0e6; # bps
set propDelay 0.05; # second
set port 1001; # for CBR traffic

set toSetupPlotFile 0
set toSetupInspect 0

Step 1. Creating the network topology

Step 1.1. We create a component directory to hold all the components created in this example:

cd [mkdir drcl.comp.Component /diffserv2]

Step 1.2.  We create the network topology:

puts "create topology..."
set link_ [java::new drcl.inet.Link]
$link_ setPropDelay $propDelay; # 50ms
set adjMatrix_ [java::new {int[][]} 9 {{1 2} {0 3 4 5} {0 6 7 8} {1} {1} {1} {2} {2} {2}}]
java::call drcl.inet.InetUtil createTopology [! .] $adjMatrix_ $link_

Step 2. Building the nodal structure.

We build the edge/core routers and the end hosts.

puts "create builders..."

# CSLBuilder:
set ccb [mkdir drcl.inet.core.CSLBuilder .cslBuilder]
set ecb [cp $ccb .edgeRouterCSLBuilder]
set hcb [cp $ccb .hostCSLBuilder]

# set up CSL builder for core router
mkdir drcl.diffserv.scheduling.pq $ccb/q1; # only at interface 1

# set up CSL builder for edge router
mkdir drcl.diffserv.TrafficConditioner $ecb/pf0_0; # only at interface 0

# set up CSL builder for source host (containing marker)
mkdir drcl.diffserv.TrafficConditioner $hcb/pf0_0;

# node builder:
set nb [mkdir drcl.inet.NodeBuilder .routerBuilder]
$nb setBandwidth 100.0e6; # 100Mbps

puts "build..."
$nb build [! n0] $ccb
$nb build [! n1] $ecb
$nb build [! n2,h8]
$nb build [! h5] $hcb
$nb build [! h3-4] $hcb {
tcp drcl.inet.transport.TCP
source -/tcp drcl.inet.application.BulkSource
}
$nb build [! h6-7] {
tcpsink drcl.inet.transport.TCPSink
sink -/tcpsink drcl.inet.application.BulkSink
}
! h3-4,h6-7/tcp* setMSS 512; #byte
! h3-4,h6-7/s* setDataUnit 512

#set cbr source
# Arguments: pkt_size interval, rate 1.2e05 bps
set traffic [java::new drcl.net.traffic.traffic_PacketTrain 150 0.01];
java::call drcl.inet.InetUtil createTrafficSource $traffic "source" [! h5] [! h8] 0 $port

# Configure the bottleneck bandwidth
! n0 setBandwidth 1 $bandwidth

# setup TCP parameters
! h3/tcp setPeer 6
! h4/tcp setPeer 7

Step 3. Setting up static routes.

We set up static routes, respectively, between h3 and h6, between h4 and h7, and between h5 and h8.

puts "setup static routes..."
java::call drcl.inet.InetUtil setupRoutes [! h3] [! h6] "bidirection"
java::call drcl.inet.InetUtil setupRoutes [! h4] [! h7] "bidirection"
java::call drcl.inet.InetUtil setupRoutes [! h5] [! h8] "bidirection"

Step 4. Setting up a Plotter component for viewing results online or offline.

We set up a TrafficMonitor component and a Plotter component to on-line keep track of  the instantaneous throughput.

puts "Set up TrafficMonitor & Plotter..."
set plot_ [mkdir drcl.comp.tool.Plotter .plot]
if {!$toSetupPlot} {
set fileName_ "ex2.plot"
puts "Set up file '$fileName_' to store results..."
setflag plot false $plot_
set file_ [mkdir drcl.comp.io.FileComponent .file]
$file_ open $fileName_
connect -c $plot_/.output@ -to $file_/in@
}
foreach i {6 7} {
set j [expr $i-6]
set k [expr $i-3]
set tm$k\_ [mkdir drcl.net.tool.TrafficMonitor .tm$k]
connect -c h$i/csl/6@up -to .tm$k/in@
connect -c .tm$k/bytecount@ -to $plot_/$j@0
connect -c h$k/tcp/cwnd@ -to $plot_/$j@1

}
! .tm? configure 4.0 0.5; # window size, update interval

foreach i {8} {
set j [expr $i-6]
set k [expr $i-3]
set tm$k\_ [mkdir drcl.net.tool.TrafficMonitor .tm$k]
connect -c h$i/csl/$port@up -to .tm$k/in@
connect -c .tm$k/bytecount@ -to $plot_/$j@0
}

Step 5. Configuring markers at hosts.

proc ConfigProfile {meterType markerType source trafficConditioner} {
if [string match "Meter" $meterType] {
set meter [java::null]
} else {
set meter [java::new drcl.diffserv.$meterType]
}
set profile [java::new drcl.diffserv.DFProfile]
$profile set [java::new drcl.diffserv.Marker $markerType] $meter
! $trafficConditioner addProfile [! $source getDefaultAddress] $profile
return $profile
}

puts "Setting up end hosts marker"
ConfigProfile "Meter" "SET_AF11" h3 h3/csl/pf0_0
ConfigProfile "Meter" "SET_AF11" h4 h4/csl/pf0_0
ConfigProfile "Meter" "SET_EF" h5 h5/csl/pf0_0

The above segment of scripts enable hosts h3, h4, and h5 to pre-mark packets as AF11, AF11 and EF respectively. Pre-marking can be used by a source node to specify the connection preference/priority class.

Step 6. Configuring the edge router.

We configure the traffic conditioner at the edge router n1.

puts "Setting up edge router"
# for host 3, we have rtt * target_rate (2.5e5) ~ 104560 bit burst to accommodate
# for host 4, we have rtt * target_rate (5.0e5) ~ 204560 bit burst to accommodate
set tg_rate 250000
set burst 104560; # bits
set p [ConfigProfile "TC_meter" "COLOR_AWARE" h3 n1/csl/pf0_0]
[!!! [$p getMeter]] config "SINGLE_RATE" $burst $tg_rate $burst 0; # last rate doesn't matter

set tg_rate 500000
set burst 204560; # bits
set p [ConfigProfile "TC_meter" "COLOR_AWARE" h4 n1/csl/pf0_0]
[!!! [$p getMeter]] config "TWO_RATE" $burst $tg_rate [expr int($burst*1.2)] [expr int($tg_rate*1.2)]

set tg_rate 136000
set burst 8000; # bits
set p [ConfigProfile "TB_meter" "POLICER" h5 n1/csl/pf0_0]
[!!! [$p getMeter]] config $burst $tg_rate;

At the edge router n1, we add a single-rate three color marker, a two-rate three color marker, and a token bucket policer, for traffic from hosts h3, h4 and h5, respectively. The target rates for hosts h3 and h4 are 0.25Mbps and 0.5Mbps, respectively. The token bucket policer will drop every packet from h5 that fails to obtain a token. 

Step 7. Configuring the core router.

We configure the HQS at core router n0.

#set up HQS with EF, AF11 and BS FIFO queue served by pq
puts "Setting up HQS"
set bs_queue [java::new drcl.inet.core.queue.DropTail "bs_q"]
set af1x_queue [java::new drcl.diffserv.scheduling.ColorQueue "af1x_q"]
#set af1x_queue [java::new drcl.inet.core.queue.DropTail "af1x_q"]
set ef_queue [java::new drcl.inet.core.queue.DropTail "ef_q"]
$bs_queue setCapacity 8000; # bytes
$af1x_queue setCapacity 16000
$ef_queue setCapacity 8000

puts "Setup 3ColorQueue"
$af1x_queue config 3000 16000 10000000 \
100 16100 100 \
100 1600 5 \
.02 $bandwidth 500
$af1x_queue reset

puts "Setup queue sets"
set dscpmask_ [java::field drcl.diffserv.DFConstants DSCPMask]
set dfclassmask_ [java::field drcl.diffserv.DFConstants DFCLASS_MASK]
! n0/csl/q1 setClassIDMask $dscpmask_
! n0/csl/q1 addQueueSet $ef_queue $dscpmask_ [java::field drcl.diffserv.DFConstants EF_TOS]
! n0/csl/q1 addQueueSet $af1x_queue $dfclassmask_ [java::field drcl.diffserv.DFConstants AF1x_TOS]
! n0/csl/q1 addQueueSet $bs_queue $dscpmask_ [java::field drcl.diffserv.DFConstants BE_TOS]

Step 8. Start simulation.

setflag garbagedisplay true recursively n0/csl/q1

puts "simulation begins..."
set sim [attach_simulator .]

$sim stop

puts "start cbr source"
run h5

puts "start tcp sources"
run h3,h4

script {puts [$sim getTime]} -period 10.0 -on $sim
$sim resumeTo 200

puts done!

Results

Figure 9: Simulation results in Example 2.

As shown in Figure 9,  host h5 (with the EF source) attains a near-constant rate of 0.125Mbp, as surplus packets are dropped at the edge router. Host h4 (with the AF source) attains higher average throughput than host h3 (also with the AF source), due to the fact that the profiled target rate at host h3 (0.25Mbps) is smaller than that at host h4 (0.5Mbps). 

The source code of this example is available here.

In summary, we have shown in this example:

  1. How to pre-mark packets at end hosts.
  2. How to set up a three-color marker at the edge router and a three-color queue at the core router.
  3. By setting target rates appropriately, service differentiation can be achieved among AF traffic sources.

References