From 3236d33b6a4a991c9ede0366f7bcb0141f74af9c Mon Sep 17 00:00:00 2001
From: Andrew Ferguson <adf@cs.brown.edu>
Date: Sun, 21 Apr 2013 15:47:37 -0400
Subject: [PATCH] allow user switch to be used with TCIntf's

---
 mininet/node.py | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/mininet/node.py b/mininet/node.py
index fc24ad21..b6fcb737 100644
--- a/mininet/node.py
+++ b/mininet/node.py
@@ -49,6 +49,7 @@
 import signal
 import select
 from subprocess import Popen, PIPE, STDOUT
+from time import sleep
 
 from mininet.log import info, error, warn, debug
 from mininet.util import ( quietRun, errRun, errFail, moveIntf, isShellBuiltin,
@@ -816,6 +817,28 @@ def dpctl( self, *args ):
         return self.cmd( 'dpctl ' + ' '.join( args ) +
                          ' tcp:127.0.0.1:%i' % self.listenPort )
 
+    @staticmethod
+    def TCReapply( intf ):
+        """Unfortunately user switch and Mininet are fighting
+           over tc queuing disciplines. To resolve the conflict,
+           we re-create the user switch's configuration, but as a
+           leaf of the TCIntf-created configuration."""
+        if type( intf ) is TCIntf:
+            ifspeed = 10000000000 # 10 Gbps
+            minspeed = ifspeed * 0.001
+
+            res = intf.config( **intf.params )
+            parent = res['parent']
+
+            # Re-add qdisc, root, and default classes user switch created, but
+            # with new parent, as setup by Mininet's TCIntf
+            intf.tc( "%s qdisc add dev %s " + parent +
+                     " handle 1: htb default 0xfffe" )
+            intf.tc( "%s class add dev %s classid 1:0xffff parent 1: htb rate "
+                     + str(ifspeed) )
+            intf.tc( "%s class add dev %s classid 1:0xfffe parent 1:0xffff " +
+                     "htb rate " + str(minspeed) + " ceil " + str(ifspeed) )
+
     def start( self, controllers ):
         """Start OpenFlow reference user datapath.
            Log to /tmp/sN-{ofd,ofp}.log.
@@ -834,6 +857,10 @@ def start( self, controllers ):
                   ' ' + clist +
                   ' --fail=closed ' + self.opts +
                   ' 1> ' + ofplog + ' 2>' + ofplog + ' &' )
+        sleep(1) # Allow ofdatapath to start before re-arranging qdisc's
+        for intf in self.intfList():
+            if not intf.IP():
+                self.TCReapply( intf )
 
     def stop( self ):
         "Stop OpenFlow reference user datapath."
-- 
GitLab