diff --git a/INSTALL b/INSTALL
index cf47bde08831139705fed44beb32df1be6dd3ba1..1542ee42bc187641ebf939e39d35c97e88e8e54d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -59,31 +59,15 @@ Preliminary Mininet Installation/Configuration Notes
   upon, and an example provided, in the future.)
   
 - For scalable configurations, you might need to increase some of your
-  kernel limits. For example, you could add something like the following
-  to /etc/sysctl.conf (modified as necessary for your desired 
+  kernel limits. Sample params are in sysctl_addon, which can be appended to
+  /etc/sysctl.conf (and modified as necessary for your desired
   configuration):
 
-    # Mininet: Increase open file limit
-    fs.file-max = 100000
-
-    # Mininet: increase network buffer space
-    net.core.wmem_max = 16777216
-    net.core.rmem_max = 16777216
-    net.ipv4.tcp_rmem = 10240 87380 16777216
-    net.ipv4.tcp_rmem = 10240 87380 16777216
-    net.core.netdev_max_backlog = 5000
-
-    # Mininet: increase arp cache size
-    net.ipv4.neigh.default.gc_thresh1 = 4096 
-    net.ipv4.neigh.default.gc_thresh2 = 8192 
-    net.ipv4.neigh.default.gc_thresh3 = 16384
-
-    # Mininet: increase routing table size
-    net.ipv4.route.max_size=32768
+    sudo su -c "cat sysctl_addon >> /etc/sysctl.conf"
 
   To save the config change, run:
 
-    sysctl -p
+    sudo sysctl -p
 
 ---
 
diff --git a/bin/mn b/bin/mn
index d0b0b6b80b337d4c71ac5f75490495962e89e338..a8ae5a85b29ca8cefea5926d9aedda847cbbed8e 100755
--- a/bin/mn
+++ b/bin/mn
@@ -3,18 +3,19 @@
 """
 Mininet runner
 author: Brandon Heller (brandonh@stanford.edu)
+
+To see options:
+  sudo mn -h
+
+Example to pull custom params (topo, switch, etc.) from a file:
+  sudo mn --custom ~/mininet/custom/custom_example.py
 """
 
 from optparse import OptionParser
 import os.path
+import sys
 import time
 
-try:
-    from ripcord.dctopo import TreeTopo, FatTreeTopo, VL2Topo
-    USERIPCORD = True
-except ImportError:
-    USERIPCORD = False
-
 from mininet.log import lg, LEVELS
 from mininet.net import Mininet, init
 from mininet.node import KernelSwitch, Host, Controller, ControllerParams, NOX
@@ -29,16 +30,6 @@ TOPOS = { 'minimal': ( lambda: SingleSwitchTopo( k=2 ) ),
          'single100': ( lambda: SingleSwitchTopo( k=100 ) ),
          'linear2': ( lambda: LinearTopo( k=2 ) ),
          'linear100': ( lambda: LinearTopo( k=100 ) ) }
-if USERIPCORD:
-    TOPOSRIPCORD = {
-         'tree16': ( lambda: TreeTopo( depth=3, fanout=4 ) ),
-         'tree64': ( lambda: TreeTopo( depth=4, fanout=4 ) ),
-         'tree1024': ( lambda: TreeTopo( depth=3, fanout=32 ) ),
-         'fattree4': ( lambda: FatTreeTopo( k=4 ) ),
-         'fattree6': ( lambda: FatTreeTopo( k=6 ) ),
-         'vl2': ( lambda: VL2Topo( da=4, di=4 ) ),
-         'vl2reduced': ( lambda: VL2Topo( da=4, di=4, edgeDown=1 ) ) }
-    TOPOS.update( TOPOSRIPCORD )
 
 SWITCHDEF = 'kernel'
 SWITCHES = { 'kernel': KernelSwitch,
@@ -57,8 +48,7 @@ CONTROLLERS = { 'ref': Controller,
                'none': lambda a, b: None }
 
 # optional tests to run
-TESTS = [ 'cli', 'build', 'pingAll', 'pingPair', 'iperf', 'all',
-    'iperfUdp' ]
+TESTS = [ 'cli', 'build', 'pingAll', 'pingPair', 'iperf', 'all', 'iperfUdp' ]
 
 
 def addDictOption( opts, choicesDict, default, name, helpStr=None ):
@@ -86,14 +76,37 @@ class MininetRunner( object ):
     def __init__( self ):
         "Init."
         self.options = None
+        self.validate = None
 
         self.parseArgs()
         self.setup()
         self.begin()
 
+    def parseCustomFile( self, custom ):
+        "Parse custom file and add params before parsing cmd-line options."
+        if os.path.isfile( custom ):
+            execfile( custom, globals(), globals() )
+            if 'topos' in globals(): TOPOS.update( topos )
+            if 'switches' in globals(): SWITCHES.update( switches )
+            if 'hosts' in globals(): HOSTS.update( hosts )
+            if 'controllers' in globals(): CONTROLLERS.update( controllers )
+            if 'validate' in globals(): self.validate = validate
+        else:
+            raise Exception( 'could not find custom file: %s' % custom )
+
     def parseArgs( self ):
         """Parse command-line args and return options object.
            returns: opts parse options dict"""
+        if '--custom' in sys.argv:
+            print "custom in sys.argv"
+            index = sys.argv.index( '--custom' )
+            if len( sys.argv ) > index + 1:
+                custom = sys.argv[ index + 1 ]
+                print "custom = %s" % custom
+                self.parseCustomFile( custom )
+            else:
+                raise Exception( 'Custom file name not found' )
+
         opts = OptionParser()
         addDictOption( opts, TOPOS, TOPODEF, 'topo' )
         addDictOption( opts, SWITCHES, SWITCHDEF, 'switch' )
@@ -101,7 +114,7 @@ class MininetRunner( object ):
         addDictOption( opts, CONTROLLERS, CONTROLLERDEF, 'controller' )
 
         opts.add_option( '--custom', type='string', default=None,
-                        help='read custom mininet from current dir' )
+                        help='read custom topo and node params from .py file' )
         opts.add_option( '--test', type='choice', choices=TESTS,
                         default=TESTS[ 0 ],
                         help='[' + ' '.join( TESTS ) + ']' )
@@ -133,18 +146,6 @@ class MininetRunner( object ):
         # validate environment setup
         init()
 
-        # check for invalid combinations
-        if ( self.options.controller == 'ref' and
-            ( ( 'fattree' in self.options.topo ) or
-              ( 'vl2' in self.options.topo ) ) ):
-            raise Exception( 'multipath topos require multipath-capable '
-                            'controller.' )
-
-        if self.options.custom:
-            if not os.path.isfile( self.options.custom ):
-                raise Exception( 'could not find custom file: %s' %
-                    self.options.custom )
-
     def begin( self ):
         "Create and run mininet."
 
@@ -159,25 +160,18 @@ class MininetRunner( object ):
                              ipAddress=self.options.ip,
                              port=self.options.port )
 
+        if self.validate:
+            self.validate(self.options)
+
         controllerParams = ControllerParams( 0x0a000000, 8 ) # 10.0.0.0/8
         inNamespace = self.options.inNamespace
         xterms = self.options.xterms
         mac = self.options.mac
         arp = self.options.arp
-        mn = None
-        if not self.options.custom:
-            mn = Mininet( topo, switch, host, controller, controllerParams,
-                         inNamespace=inNamespace,
-                         xterms=xterms, autoSetMacs=mac,
-                         autoStaticArp=arp )
-        else:
-            globals_ = {}
-            locals_ = {}
-            execfile( self.options.custom, globals_, locals_ )
-            if 'mn' not in locals_:
-                raise Exception( 'could not find mn var in custom file' )
-            else:
-                mn = locals_[ 'mn' ]
+        mn = Mininet( topo, switch, host, controller, controllerParams,
+                     inNamespace=inNamespace,
+                     xterms=xterms, autoSetMacs=mac,
+                     autoStaticArp=arp )
 
         test = self.options.test
         if test != 'build':
diff --git a/custom/custom_example.py b/custom/custom_example.py
index 9670890f88e09d2904f3411cf662fb98638402a2..49e23942cd7bf89e31376e64ee783bb038f2a565 100644
--- a/custom/custom_example.py
+++ b/custom/custom_example.py
@@ -1,25 +1,45 @@
-'''Example of custom topo
+"""Custom topology example
 
-@author Brandon Heller (brandonh@stanford.edu)
+author: Brandon Heller (brandonh@stanford.edu)
 
-'''
+Two directly connected switches plus a host for each switch:
 
-from mininet.topo import SingleSwitchTopo
-from mininet.net import Mininet
-from mininet.node import KernelSwitch, Host, Controller, ControllerParams
+   host --- switch --- switch --- host
 
-topo = SingleSwitchTopo(k = 2) # build topology object
-switch = KernelSwitch
-host = Host
-controller = Controller
-controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
-in_namespace = False
-xterms = False
-mac = True
-arp = True
+Adding the 'topos' dict with a key/value pair to generate our newly defined
+topology enables one to pass in '--topo=mytopo' from the command line.
+"""
 
-mn = Mininet(topo, switch, host, controller, controller_params,
-             in_namespace = in_namespace,
-             xterms = xterms, auto_set_macs = mac,
-             auto_static_arp = arp)
+from mininet.topo import Topo, Node
 
+class MyTopo( Topo ):
+    """Simple topology example."""
+
+    def __init__( self, enable_all = True ):
+        """Create custom topo."""
+
+        # Add default members to class.
+        super( MyTopo, self ).__init__()
+
+        # Set Node IDs for hosts and switches
+        leftHost = 1
+        leftSwitch = 2
+        rightSwitch = 3
+        rightHost = 4
+
+        # Add nodes
+        self._add_node( leftSwitch, Node( is_switch=True ) )
+        self._add_node( rightSwitch, Node( is_switch=True ) )
+        self._add_node( leftHost, Node( is_switch=False ) )
+        self._add_node( rightHost, Node( is_switch=False ) )
+
+        # Add edges
+        self._add_edge( leftHost, leftSwitch )
+        self._add_edge( leftSwitch, rightSwitch )
+        self._add_edge( rightSwitch, rightHost )
+
+        # Consider all switches and hosts 'on'
+        self.enable_all()
+
+
+topos = { 'mytopo': ( lambda: MyTopo() ) }
\ No newline at end of file
diff --git a/mininet/topo.py b/mininet/topo.py
index 768c591739964b71dcb10171511a1f4285590079..3ff9cb87f7eaa924099f6a58e0cd75501a2f9789 100644
--- a/mininet/topo.py
+++ b/mininet/topo.py
@@ -107,7 +107,7 @@ def _add_node(self, dpid, node):
         self.g.add_node(dpid)
         self.node_info[dpid] = node
 
-    def _add_edge(self, src, dst, edge):
+    def _add_edge(self, src, dst, edge = None):
         '''Add edge (Node, Node) to graph.
 
         @param src src dpid
@@ -116,6 +116,8 @@ def _add_edge(self, src, dst, edge):
         '''
         src, dst = tuple(sorted([src, dst]))
         self.g.add_edge(src, dst)
+        if not edge:
+            edge = Edge()
         self.edge_info[(src, dst)] = edge
         self._add_port(src, dst)
 
diff --git a/sysctl_addon b/sysctl_addon
new file mode 100644
index 0000000000000000000000000000000000000000..e26eecc2222b93477b6af123e654e6b29706c90c
--- /dev/null
+++ b/sysctl_addon
@@ -0,0 +1,17 @@
+# Mininet: Increase open file limit
+fs.file-max = 100000
+
+# Mininet: increase network buffer space
+net.core.wmem_max = 16777216
+net.core.rmem_max = 16777216
+net.ipv4.tcp_rmem = 10240 87380 16777216
+net.ipv4.tcp_rmem = 10240 87380 16777216
+net.core.netdev_max_backlog = 5000
+
+# Mininet: increase arp cache size
+net.ipv4.neigh.default.gc_thresh1 = 4096 
+net.ipv4.neigh.default.gc_thresh2 = 8192 
+net.ipv4.neigh.default.gc_thresh3 = 16384
+
+# Mininet: increase routing table size
+net.ipv4.route.max_size=32768