From c069542c5cfc5b51eb919eb9e56ff569951a935f Mon Sep 17 00:00:00 2001
From: Bob Lantz <rlantz@cs.stanford.edu>
Date: Tue, 18 Nov 2014 14:45:30 -0800
Subject: [PATCH] Add OVSLink/--link ovs, which uses OVS patch links when
 possible

---
 bin/mn          |  5 +++--
 mininet/link.py | 33 +++++++++++++++++++++++++++++++++
 mininet/node.py | 15 ++++++++++++++-
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/bin/mn b/bin/mn
index bace2fe7..bdb5ea31 100755
--- a/bin/mn
+++ b/bin/mn
@@ -30,7 +30,7 @@ from mininet.node import ( Host, CPULimitedHost, Controller, OVSController,
                            UserSwitch, OVSSwitch, OVSBridge,
                            OVSLegacyKernelSwitch, IVSSwitch )
 from mininet.nodelib import LinuxBridge
-from mininet.link import Link, TCLink
+from mininet.link import Link, TCLink, OVSLink
 from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
 from mininet.topolib import TreeTopo, TorusTopo
 from mininet.util import customConstructor, splitArgs
@@ -82,7 +82,8 @@ CONTROLLERS = { 'ref': Controller,
 
 LINKDEF = 'default'
 LINKS = { 'default': Link,
-          'tc': TCLink }
+          'tc': TCLink,
+          'ovs': OVSLink }
 
 
 # optional tests to run
diff --git a/mininet/link.py b/mininet/link.py
index e5b85e1b..b5eca520 100644
--- a/mininet/link.py
+++ b/mininet/link.py
@@ -26,6 +26,7 @@
 
 from mininet.log import info, error, debug
 from mininet.util import makeIntfPair, quietRun
+import mininet.node
 import re
 
 class Intf( object ):
@@ -453,6 +454,38 @@ def status( self ):
     def __str__( self ):
         return '%s<->%s' % ( self.intf1, self.intf2 )
 
+
+class OVSIntf( Intf ):
+    "Patch interface on an OVSSwitch"
+
+    def ifconfig( self, cmd ):
+        if cmd == 'up':
+            "OVSIntf is always up"
+            return
+        else:
+            raise Exception( 'OVSIntf cannot do ifconfig ' + cmd )
+
+
+class OVSLink( Link ):
+    "Link that makes patch links between OVSSwitches"
+
+    def __init__( self, node1, node2, **kwargs ):
+        "See Link.__init__() for options"
+        self.isPatchLink = False
+        if ( type( node1 ) is mininet.node.OVSSwitch and
+             type( node2 ) is mininet.node.OVSSwitch ):
+             self.isPatchLink = True
+             kwargs.update( cls1=OVSIntf, cls2=OVSIntf )
+        Link.__init__( self, node1, node2, **kwargs )
+
+    def makeIntfPair( self, *args, **kwargs ):
+        "Usually delegated to OVSSwitch"
+        if self.isPatchLink:
+            return None, None
+        else:
+            return Link.makeIntfPair( *args, **kwargs )
+
+
 class TCLink( Link ):
     "Link with symmetric TC interfaces configured via opts"
     def __init__( self, node1, node2, port1=None, port2=None,
diff --git a/mininet/node.py b/mininet/node.py
index 27612193..142f2552 100644
--- a/mininet/node.py
+++ b/mininet/node.py
@@ -58,7 +58,7 @@
 from mininet.util import ( quietRun, errRun, errFail, moveIntf, isShellBuiltin,
                            numCores, retry, mountCgroups )
 from mininet.moduledeps import moduleDeps, pathCheck, OVS_KMOD, OF_KMOD, TUN
-from mininet.link import Link, Intf, TCIntf
+from mininet.link import Link, Intf, TCIntf, OVSIntf
 from re import findall
 from distutils.version import StrictVersion
 
@@ -1147,6 +1147,18 @@ def connected( self ):
                 return True
         return self.failMode == 'standalone'
 
+    @staticmethod
+    def patchOpts( intf ):
+        "Return OVS patch port options (if any) for intf"
+        if type( intf ) is not OVSIntf:
+            # Ignore if it's not a patch link
+            return ''
+        intf1, intf2 = intf.link.intf1, intf.link.intf2
+        peer = intf1 if intf1 != intf else intf2
+        return ( '-- set Interface %s type=patch '
+                 '-- set Interface %s options:peer=%s ' %
+                 ( intf, intf, peer ) )
+
     def start( self, controllers ):
         "Start up a new OVS OpenFlow switch using ovs-vsctl"
         if self.inNamespace:
@@ -1159,6 +1171,7 @@ def start( self, controllers ):
         intfs = ' '.join( '-- add-port %s %s ' % ( self, intf ) +
                           '-- set Interface %s ' % intf +
                           'ofport_request=%s ' % self.ports[ intf ]
+                          + self.patchOpts( intf )
                           for intf in self.intfList()
                           if self.ports[ intf ] and not intf.IP() )
         clist = ' '.join( '%s:%s:%d' % ( c.protocol, c.IP(), c.port )
-- 
GitLab