myEvalSVC-Mininet: H.264 SVC video transmission evaluation over Mininet

 

[Description]

        Based on SVEF (Scalable Video-streaming Evaluation Framework), NCTUNS(or EstiNet), and my previous work, myEvalSVC, I developed myEvalSVC-Mininet version for H.264 SVC video transmission evaluation over Mininet environment. Therefore, please read all related web sites before using myEvalSVC-Mininet, especially the following paper if you want to know more about H.264 SVC transmission evaluation.

 

C. H. Ke, " myEvalSVC: an Integrated Simulation Framework for Evaluation of H.264/SVC Transmission ", KSII Transactions on Internet and Information Systems, vol. 6, no. 1, pp. 378-393, Jan. 2012 (SCI)

 

[Prerequiste]

1.     Install JSVM reference software in your environment. Refer this for some information.

2.     Download the toolset from  SVEF and be familiar with each instruction.

3.     Download the source code of myrtg_svc.c (video receiver) and mystg_svc.c (video sender) if you want to conduct more complicated scenarios.

4.     Download myfixyuv.c for fixing the distorted video.

5.     Download the testing raw YUV video, i.e. foreman_cif.yuv.

 

[Example 1: One switch and two hosts. Host 1 is sending the video to Host 2.]

1.      Do temporal encoding/decoding process.

1.1  prepare the configuration file.

(temporal_main.cfg)

OutputFile       temporal.264

FrameRate      30.0

FramesToBeEncoded 300

GOPSize           4

BaseLayerMode      2

IntraPeriod      4

 

SearchMode    4

SeachRange    32

NumLayers      1

LayerCfg  temporal_layer0.cfg

 

(temporal_layer0.cfg)

InputFile  foreman_cif.yuv

SourceWidth   352

SourceHeight  288

FrameRateIn   30

FrameRateOut        30

 

1.2  Encoding.

 

1.3. Decode the temporal.264 and record the decoding process into temporal_originaldecoderoutput.txt. We need some information from it.

 

2.        Use the JSVM BitStreamExtractor to generate the original NALU trace file (temporal_originaltrace.txt)

     

 

3.      Use f-nstamp to add the frame-number in temporal_originaltrace.txt. (It will generate temporal_originaltrace-frameno.txt)

 

4.      Run the mininet script (mymininet2_temporalvideo.py) (Remember to copy streamer and receiver from svef folder to the place that you put mymininet2_temporalvideo.py)

#!/usr/bin/python

 

from mininet.topo import Topo

from mininet.net import Mininet

from mininet.node import CPULimitedHost

from mininet.link import TCLink

from mininet.util import dumpNodeConnections

from mininet.log import setLogLevel

from mininet.node import Controller

import os

 

class SingleSwitchTopo(Topo):

    "Single switch connected to n hosts."

    def __init__(self, n=2, **opts):

        Topo.__init__(self, **opts)

        switch = self.addSwitch('s1')

        for h in range(n):

            #Each host gets 50%/n of system CPU

            host = self.addHost('h%s' % (h + 1), cpu=.5/n)

            #100 Mbps, 1ms delay, 1% Loss, 1000 packet queue

            self.addLink(host, switch, bw=10, delay='1ms', loss=1)

 

def perfTest():

    "Create network and run simple performance test"

    topo = SingleSwitchTopo(n=2)

    net = Mininet(topo=topo,host=CPULimitedHost,link=TCLink)

    net.start()

    dumpNodeConnections(net.hosts)

    h1, h2 = net.get('h1', 'h2')

    net.pingAll()

    print "Testing video transmission between h1 and h2"

    h2.cmd('sudo ./receiver 4455 myout.264 15000 > myreceivedtrace.txt &')

    h1.cmd('sudo ./streamer temporal_originaltrace-frameno.txt 30 10.0.0.2 4455 temporal.264 1 > mysent.txt')

    net.stop()

 

if __name__=='__main__':

    setLogLevel('info')

           perfTest()

 

5.      Based on temporal_originaltrace-frameno.txt and received file, nalufilter will discard too late frames and frames that cannot be decoded due to frame dependencies.

 

6.  The current version of JSVM (9.19.8) cannot decode video streams affected by out of order, corrupted, or missing NALUs. Therefore, SVEF uses filtered packet trace file to extract the corresponding packets in original h.264 video file by means of BitStreamExtractorStatic. (You can think that processed video file corresponds to the actually useful data received at the receiving side.)

  

   ………………………………………………………………………………………………………………………..

  

 

7.     Decode the temporal-filtered.264 file.

 

8.      We need the same number of video frames when we want to calculate the PSNR of original YUV and receiving YUV file. So we need to conceal the missing frames by copying the previous frame.

 

9.  Now you can compare the PSNR.

  

 

In the following two examples, I will compare the delivered video qualities over two different transmission schemes. The first one is that all video packets are transmitted in the same path while the second one is the different priorities of packets go in different paths. The simulation topology is that

 

                            -------------- s1 -----------

                           |                                         |

h0 (sender)----s0----------  s2----------------  s4 -----------h1(receiver)

                           |                                         |

                            -----------  s3---------------

 

s0,s1,s2,s3 are all switches. Assume that the path h0-s0-s3-s4-h1 has the largest bandwidth. However, this path has the highest loss rate. Example 2 will show the delivered video quality when video is transmitted over h0-s0-s3-s4-h1.

In example 3, h0-s0-s1-s4-h1 has the smallest bandwidth, but has the lowest loss rate. h0-s0-s2-s4 has the middle bandwidth and the middle loss rate. h0-s0-s3-s4-h1 has the largest bandwidth but has the highest loss rate. We will see the delivered video quality.

  In these two examples, we assume that the controller has already known all the information. Therefore, we directly set the rule in the switches. In the future, a smarter controller should be designed to provide a better delivered video quality over dynamic network scenario.

 

[Important: I modified the stg/rtg programs in NCTUns-6.0 to mystg_svc/myrtg_svc. The program, mystg_svc, will read the trace and send the corresponding packet at the pre-defined time to network. Also, this program will set the ToS field in the IP header according to the value saved in the trace file. In our examples, the value 100 is the most important packet, 110 is the middle important packet, and 120 is the least important packet. The program, myrtg_svc, is the receiver program that can show the information for each received packet. The information will be used for post processing.

 

[Example 2:]

1.      Do the same steps from 1 to 3 in the example 1.

2.      Prepare the sending trace needed by SVEF with the aid of prepare_sendtrace.awk

#This file is prepare_sendtrace.awk

BEGIN{

  time=500; # It means that this SVC video starts transmission at 0.5 second.

                 # If you want to start transmission at 1.0 second, change the value to 1000.

  i=0;

}

{

  if($6=="SliceData"){

    printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%ld\n",$1,$2,$3,$4,$5,$6,$7,$8,$9,time);

    if(i==0) {

       i=1;

    } else {

      time+=1000.0/30.0;

      i=0;

    }

  } else {

    printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",$1,$2,$3,$4,$5,$6,$7,$8,$9,0);

  }

}

END{

}

 

3.  Prepare the NS2 sending trace needed by myEvalSVC agent with the aid of prepare_ns2sendtrace.awk. (Do it. Because my work was ported from NS2 environment.)

BEGIN{

  i=0;

  FrameSize=0;

  time=1.0/30.0;

}

{

  StartPos=$1;

  Length=$2;

  LId=$3;

  TId=$4;

  QId=$5;

  PacketType=$6;

  Discardable=$7;

  Truncatable=$8;

  FrameNo=$9;

  SentTime=$10;

  if(i==0 && PacketType=="SliceData") {

    FrameSize=(Length+12);

    i=1;

  }else if (i==1 && PacketType=="SliceData") {

    FrameSize+=(Length+12);

    printf("%f\t%s\t%s\t%s\t%s\t%s\n", time, FrameSize, LId, TId, QId, FrameNo);

    time+=1.0/30.0;

    i=0;

    FrameSize=0;

  }

}

END{

}

 

4.  Execute the following command to transform the ns2send to the format that is required by mstg_svc

BEGIN{

  seg_size=1024;

  pre_time = 0.0;

}

{

  frame_sent_time=$1;

  frame_size=$2;

  frame_lid=$3;

  frame_tid=$4;

  frame_qid=$5;

  frame_no=$6;

 

  if(frame_tid==0)

    tos=100;

 

  if(frame_tid==1)

    tos=110;

 

  if(frame_tid==2)

    tos=120;

 

  if(frame_size > seg_size) {

     i=frame_size/seg_size;

     j=frame_size%seg_size;

     # printf("frame_no:%d frame_size:%d i=%d j=%d\n", frame_no, frame_size, i, j);

 

     if(j>10) {

 

       for(k=1;k<i;k++) {

         printf("%d\t%f\t%d\t%d\n", seg_size, 0.00, tos, frame_no);

       }

       printf("%d\t%f\t%d\t%d\n", j, frame_sent_time - pre_time, tos, frame_no);      

       pre_time=frame_sent_time;

    

     } else {

           

       for(k=1;k<i-1;k++) {

         printf("%d\t%f\t%d\t%d\n", seg_size, 0.00, tos, frame_no);

       }

       printf("%d\t%f\t%d\t%d\n", j+seg_size, frame_sent_time - pre_time, tos, frame_no);      

       pre_time=frame_sent_time;        

 

     }

 

  } else {

     printf("%d\t%f\t%d\t%d\n",frame_size, frame_sent_time - pre_time, tos, frame_no);

     pre_time=frame_sent_time;

  }

 

}

END{

}

 

5.      Run the mininet script. (mymininet5_temporalvideo.py)

#!/usr/bin/python

 

from mininet.net import Mininet

from mininet.node import Node

from mininet.link import TCLink

from mininet.log import  setLogLevel, info

 

def myNet():

    "Create network from scratch using Open vSwitch."

 

    info( "*** Creating nodes\n" )

    switch0 = Node( 's0', inNamespace=False )

    switch1 = Node( 's1', inNamespace=False )

    switch2 = Node( 's2', inNamespace=False )

    switch3 = Node( 's3', inNamespace=False )

    switch4 = Node( 's4', inNamespace=False )

    h0 = Node( 'h0' )

    h1 = Node( 'h1' )

 

    info( "*** Creating links\n" )

    linkopts0=dict(bw=100, delay='1ms', loss=0)

    linkopts1=dict(bw=1, delay='10ms', loss=0)

    linkopts2=dict(bw=10, delay='5ms', loss=1)

    linkopts3=dict(bw=100, delay='1ms', loss=3)

    TCLink( h0, switch0, **linkopts0)

    TCLink( switch0, switch1, **linkopts0)

    TCLink( switch0, switch2, **linkopts0)

    TCLink( switch0, switch3, **linkopts0)

    TCLink( switch1, switch4,**linkopts1)

    TCLink( switch2, switch4,**linkopts2)

    TCLink( switch3, switch4,**linkopts3)

    TCLink( h1, switch4, **linkopts0)

 

    info( "*** Configuring hosts\n" )

    h0.setIP( '192.168.123.1/24' )

    h1.setIP( '192.168.123.2/24' )

    info( str( h0 ) + '\n' )

    info( str( h1 ) + '\n' )

       

    info( "*** Starting network using Open vSwitch\n" )

    switch0.cmd( 'ovs-vsctl del-br dp0' )

    switch0.cmd( 'ovs-vsctl add-br dp0' )

    switch1.cmd( 'ovs-vsctl del-br dp1' )

    switch1.cmd( 'ovs-vsctl add-br dp1' )

    switch2.cmd( 'ovs-vsctl del-br dp2' )

    switch2.cmd( 'ovs-vsctl add-br dp2' )

    switch3.cmd( 'ovs-vsctl del-br dp3' )

    switch3.cmd( 'ovs-vsctl add-br dp3' )

    switch4.cmd( 'ovs-vsctl del-br dp4' )

    switch4.cmd( 'ovs-vsctl add-br dp4' )

 

    for intf in switch0.intfs.values():

        print intf

        print switch0.cmd( 'ovs-vsctl add-port dp0 %s' % intf )

 

    for intf in switch1.intfs.values():

        print intf

        print switch1.cmd( 'ovs-vsctl add-port dp1 %s' % intf )

 

    for intf in switch2.intfs.values():

        print intf

        print switch2.cmd( 'ovs-vsctl add-port dp2 %s' % intf )

 

    for intf in switch3.intfs.values():

        print intf

        print switch3.cmd( 'ovs-vsctl add-port dp3 %s' % intf )

 

    for intf in switch4.intfs.values():

        print intf

        print switch4.cmd( 'ovs-vsctl add-port dp4 %s' % intf )

 

    # Note: controller and switch are in root namespace, and we

    # can connect via loopback interface

    switch0.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )

    switch1.cmd( 'ovs-vsctl set-controller dp1 tcp:127.0.0.1:6633' )

    switch2.cmd( 'ovs-vsctl set-controller dp2 tcp:127.0.0.1:6633' )

    switch3.cmd( 'ovs-vsctl set-controller dp3 tcp:127.0.0.1:6633' )

    switch4.cmd( 'ovs-vsctl set-controller dp4 tcp:127.0.0.1:6633' )

 

    switch0.cmd( 'ovs-ofctl add-flow dp0 \"in_port=1 actions=output:4"' )

    switch0.cmd( 'ovs-ofctl add-flow dp0 \"in_port=4 actions=output:1\"' )

    switch3.cmd( 'ovs-ofctl add-flow dp3 \"in_port=1 actions=output:2\"' )

    switch3.cmd( 'ovs-ofctl add-flow dp3 \"in_port=2 actions=output:1\"' )

    switch4.cmd( 'ovs-ofctl add-flow dp4 \"in_port=3 actions=output:4\"' )

    switch4.cmd( 'ovs-ofctl add-flow dp4 \"in_port=4 actions=output:3\"' )

 

    #print switch0.cmd( 'ovs-ofctl show dp0' )    

    #print switch1.cmd( 'ovs-ofctl show dp1' )

    #print switch2.cmd( 'ovs-ofctl show dp2' )

    #print switch3.cmd( 'ovs-ofctl show dp3' )

    #print switch4.cmd( 'ovs-ofctl show dp4' )

 

    #info( "*** Running test\n" )

    h0.cmdPrint( 'ping –c 3 ' + h1.IP() )

 

    print "Testing video transmission between h1 and h2"

    h1.cmd('./myrtg_svc -u > myrd &')

    h0.cmd('./mystg_svc -trace st 192.168.123.2')

 

    info( "*** Stopping network\n" )

    switch0.cmd( 'ovs-vsctl del-br dp0' )

    switch0.deleteIntfs()

    switch1.cmd( 'ovs-vsctl del-br dp1' )

    switch1.deleteIntfs()

    switch2.cmd( 'ovs-vsctl del-br dp2' )

    switch2.deleteIntfs()

    switch3.cmd( 'ovs-vsctl del-br dp3' )

    switch3.deleteIntfs()

    switch4.cmd( 'ovs-vsctl del-br dp4' )

    switch4.deleteIntfs()

    info( '\n' )

 

if __name__ == '__main__':

    setLogLevel( 'info' )

    info( '*** Scratch network demo (kernel datapath)\n' )

    Mininet.init()

    myNet()

 

6.     Convert the recived file to the format required for SVEF file with the aid of prepare_receivedtrace1.awk and prepare_receivedtrace2

(prepare_receivedtrace1.awk)

BEGIN{

 i=0;

}

{

  time=$1;

  len=$2;

  tos=$3;

  sentid=$4;

  frameno=$5; 

 

  if(tos==100)

   tid=0;

  if(tos==110)

   tid=1;

  if(tos==120)

   tid=2;

 

  lid=0;

  qid=0;

 

  if(frameno>i)

     i=frameno;

 

  FrameLen[frameno]+=(len);

 

  if(time>FrameRcvTime[frameno]){

    FrameRcvTime[frameno]=time;

  }

 

    FrameLid[frameno]=lid;

    FrameTid[frameno]=tid;

    FrameQid[frameno]=qid;

}

END{

 

   for(j=0;j<=i;j++)

     if(FrameLen[j]!=0)

       printf("%f\t%d\t%d\t%d\t%d\t%d\n", FrameRcvTime[j], FrameLen[j], FrameLid[j], FrameTid[j], FrameQid[j], j);

 

}

 

(prepare_receivedtrace2.c)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define  MaxNo        1000  // assume that the max number of video is 1000

 

int main(int n, char *cl[])

{

  FILE *f1, *f2, *f3;

  int i,j;

  int IsFrameOK[MaxNo];

  double SndTime[MaxNo], RcvTime[MaxNo];

  double SndTime_, RcvTime_; 

  int SndSize[MaxNo], SndLid[MaxNo], SndTid[MaxNo], SndQid[MaxNo];

  int RcvSize[MaxNo], RcvLid[MaxNo], RcvTid[MaxNo], RcvQid[MaxNo];

  int SndSize_, SndLid_, SndTid_, SndQid_, SndFrameNo_;

  int RcvSize_, RcvLid_, RcvTid_, RcvQid_, RcvFrameNo_;

  int MaxFrameNo=0;

  char startpos[20], type[20], yorn1[20], yorn2[20];

  int  len, lid, tid, qid, no, time;

 

 

  for(i=0;i<MaxNo;i++)

    IsFrameOK[i]=-1;

 

  if(n!=4)

  {

   puts("prepare_receivedtrace2 <ns2send> <ns2received> <originaltrace-frameno.txt");

   return EXIT_FAILURE;

  }

 

  if ((f1 = fopen(cl[1],"r")) == 0) goto A;

  if ((f2 = fopen(cl[2],"r")) == 0) goto B;

  if ((f3 = fopen(cl[3],"r")) == 0) goto B;

 

  while(!feof(f1)){

    fscanf(f1, "%lf%d%d%d%d%d", &SndTime_, &SndSize_, &SndLid_, &SndTid_, &SndQid_, &SndFrameNo_);

    //printf("%lf\t%d\t%d\t%d\t%d\t%d\n", SndTime_, SndSize_, SndLid_, SndTid_, SndQid_, SndFrameNo_);

    if(MaxFrameNo<SndFrameNo_)

      MaxFrameNo=SndFrameNo_;

    SndTime[SndFrameNo_]=SndTime_;

    SndSize[SndFrameNo_]=SndSize_;

    SndLid[SndFrameNo_]=SndLid_;

    SndTid[SndFrameNo_]=SndTid_;

    SndQid[SndFrameNo_]=SndQid_; 

  }

 

  while(!feof(f2)){

    fscanf(f2, "%lf%d%d%d%d%d", &RcvTime_, &RcvSize_, &RcvLid_, &RcvTid_, &RcvQid_, &RcvFrameNo_);

    //printf("%lf\t%d\t%d\t%d\t%d\t%d\n", RcvTime_, RcvSize_, RcvLid_, RcvTid_, RcvQid_, RcvFrameNo_);

    RcvTime[RcvFrameNo_]=RcvTime_;

    RcvSize[RcvFrameNo_]=RcvSize_;

    RcvLid[RcvFrameNo_]=RcvLid_;

    RcvTid[RcvFrameNo_]=RcvTid_;

    RcvQid[RcvFrameNo_]=RcvQid_; 

  }

 

  for(i=0;i<=MaxFrameNo;i++){

    if(RcvSize[i]>=SndSize[i])

      IsFrameOK[i]=1;

  }

 

  //for(i=0;i<=MaxFrameNo;i++){

  //  if(IsFrameOK[i]==-1)

  //    printf("Frame #%d is not OK\n", i);

  //}

 

  i=0;

  while(!feof(f3)){

    fscanf(f3, "%s%d%d%d%d%s%s%s%d%d", startpos, &len, &lid, &tid, &qid, type, yorn1, yorn2, &no, &time);

    i++;

  } 

 

  //printf("num of line: %d\n", i);

 

  rewind(f3);

  for(j=1;j<i;j++){

    fscanf(f3, "%s%d%d%d%d%s%s%s%d%d", startpos, &len, &lid, &tid, &qid, type, yorn1, yorn2, &no, &time);

    //printf("%s %d %d %d %d %s %s %s %d %d\n", startpos, len, lid, tid, qid, type, yorn1, yorn2, no, time);

    if(strcmp(type, "SliceData")==0){

      if(IsFrameOK[no]==1){

         printf("%s  %6d  %3d  %3d  %3d     %s  %10s  %10s  %8d  %8ld\n", startpos, len, lid, tid, qid, type, yorn1, yorn2, no, (long)(RcvTime[no]*1000));

      }

    }

  }

 

 

  return 0;   

 

A: fprintf(stderr, " Error opening <ns2send>.\n"); goto X;

B: fprintf(stderr, " Error opening <ns2received>.\n"); goto X;

C: fprintf(stderr, " Error opening <originaltrace-frameno.txt>.\n"); goto X;

 

X: return EXIT_FAILURE;

}

 

 

7.      Then do the same steps from 5 to 9 in the example 1.

 

 

 

 

 [Example 3]

1.      Do the same steps from 1 to 4 in the example 2.

2.      Run the mininet script. (mymininet6_temporalvideo.py)

#!/usr/bin/python

 

from mininet.net import Mininet

from mininet.node import Node

from mininet.link import TCLink

from mininet.log import  setLogLevel, info

 

def myNet():

    "Create network from scratch using Open vSwitch."

 

    info( "*** Creating nodes\n" )

    switch0 = Node( 's0', inNamespace=False )

    switch1 = Node( 's1', inNamespace=False )

    switch2 = Node( 's2', inNamespace=False )

    switch3 = Node( 's3', inNamespace=False )

    switch4 = Node( 's4', inNamespace=False )

    h0 = Node( 'h0' )

    h1 = Node( 'h1' )

 

    info( "*** Creating links\n" )

    linkopts0=dict(bw=100, delay='1ms', loss=0)

    linkopts1=dict(bw=1, delay='100ms', loss=0)

    linkopts2=dict(bw=10, delay='10ms', loss=1)

    linkopts3=dict(bw=100, delay='1ms', loss=3)

    TCLink( h0, switch0, **linkopts0)

    TCLink( switch0, switch1, **linkopts0)

    TCLink( switch0, switch2, **linkopts0)

    TCLink( switch0, switch3, **linkopts0)

    TCLink( switch1, switch4,**linkopts1)

    TCLink( switch2, switch4,**linkopts2)

    TCLink( switch3, switch4,**linkopts3)

    TCLink( h1, switch4, **linkopts0)

 

    info( "*** Configuring hosts\n" )

    h0.setIP( '192.168.123.1/24' )

    h1.setIP( '192.168.123.2/24' )

    info( str( h0 ) + '\n' )

    info( str( h1 ) + '\n' )

       

    info( "*** Starting network using Open vSwitch\n" )

    switch0.cmd( 'ovs-vsctl del-br dp0' )

    switch0.cmd( 'ovs-vsctl add-br dp0' )

    switch1.cmd( 'ovs-vsctl del-br dp1' )

    switch1.cmd( 'ovs-vsctl add-br dp1' )

    switch2.cmd( 'ovs-vsctl del-br dp2' )

    switch2.cmd( 'ovs-vsctl add-br dp2' )

    switch3.cmd( 'ovs-vsctl del-br dp3' )

    switch3.cmd( 'ovs-vsctl add-br dp3' )

    switch4.cmd( 'ovs-vsctl del-br dp4' )

    switch4.cmd( 'ovs-vsctl add-br dp4' )

 

    for intf in switch0.intfs.values():

        print intf

        print switch0.cmd( 'ovs-vsctl add-port dp0 %s' % intf )

 

    for intf in switch1.intfs.values():

        print intf

        print switch1.cmd( 'ovs-vsctl add-port dp1 %s' % intf )

 

    for intf in switch2.intfs.values():

        print intf

        print switch2.cmd( 'ovs-vsctl add-port dp2 %s' % intf )

 

    for intf in switch3.intfs.values():

        print intf

        print switch3.cmd( 'ovs-vsctl add-port dp3 %s' % intf )

 

    for intf in switch4.intfs.values():

        print intf

        print switch4.cmd( 'ovs-vsctl add-port dp4 %s' % intf )

   

    print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=1,actions=flood' )

    print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=1,actions=output:2' ) 

    print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=2,actions=output:1' )

    print switch2.cmd(r'ovs-ofctl add-flow dp2 idle_timeout=0,priority=1,in_port=1,actions=output:2' )

    print switch2.cmd(r'ovs-ofctl add-flow dp2 idle_timeout=0,priority=1,in_port=2,actions=output:1' )

    print switch3.cmd(r'ovs-ofctl add-flow dp3 idle_timeout=0,priority=1,in_port=1,actions=output:2' )    

    print switch3.cmd(r'ovs-ofctl add-flow dp3 idle_timeout=0,priority=1,in_port=2,actions=output:1' )

    print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=1,actions=output:4' )

    print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=2,actions=output:4' )

    print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=3,actions=output:4' )

    print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=4,actions=output:3' )

 

    #print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,actions=output:4') 

    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x64,actions=output:2') 

    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x6E,actions=output:3')

    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x78,actions=output:4') 

   

    #switch0.cmd('tcpdump -i s0-eth0 -U -w aaa &')

    #h0.cmd('tcpdump -i h0-eth0 -U -w aaa &')

    #info( "*** Running test\n" )

    h0.cmdPrint( 'ping -Q 0x64 -c 5 ' + h1.IP() )

    h0.cmdPrint( 'ping -Q 0x6E -c 5 ' + h1.IP() )

    h0.cmdPrint( 'ping -Q 0x78 -c 5 ' + h1.IP() )

  

    print "Testing video transmission between h1 and h2"

    h1.cmd('./myrtg_svc -u > myrd &')

    h0.cmd('./mystg_svc -trace st 192.168.123.2')

  

    #print switch0.cmd( 'ovs-ofctl show dp0' )    

    #print switch1.cmd( 'ovs-ofctl show dp1' )

    #print switch2.cmd( 'ovs-ofctl show dp2' )

    #print switch3.cmd( 'ovs-ofctl show dp3' )

    #print switch4.cmd( 'ovs-ofctl show dp4' )  

    #print switch0.cmd( 'ovs-ofctl dump-tables  dp0' )

    #print switch0.cmd( 'ovs-ofctl dump-ports   dp0' )

    #print switch0.cmd( 'ovs-ofctl dump-flows  dp0' )

    #print switch0.cmd( 'ovs-ofctl dump-aggregate  dp0' )

    #print switch0.cmd( 'ovs-ofctl queue-stats dp0' )

 

    info( "*** Stopping network\n" )

    switch0.cmd( 'ovs-vsctl del-br dp0' )

    switch0.deleteIntfs()

    switch1.cmd( 'ovs-vsctl del-br dp1' )

    switch1.deleteIntfs()

    switch2.cmd( 'ovs-vsctl del-br dp2' )

    switch2.deleteIntfs()

    switch3.cmd( 'ovs-vsctl del-br dp3' )

    switch3.deleteIntfs()

    switch4.cmd( 'ovs-vsctl del-br dp4' )

    switch4.deleteIntfs()

    info( '\n' )

 

if __name__ == '__main__':

    setLogLevel( 'info' )

    info( '*** Scratch network demo (kernel datapath)\n' )

    Mininet.init()

    myNet()

 

 

 

 

 

 

From the results that we can see the result obtained in example 3 is better than that in example 2.

 

Dr. Chih-Heng Ke

Department of Computer Science and Information Engineering, National Quemoy University, Kinmen, Taiwan

Email: smallko@gmail.com / smallko@hotmail.com