Add fabric.p4 basic 2x2 topology

Change-Id: I121b042cc519bdddad313ea83fd3d3e3d1d4d217
diff --git a/trellis/trellisp4.json b/trellis/trellisp4.json
new file mode 100644
index 0000000..5fa8849
--- /dev/null
+++ b/trellis/trellisp4.json
@@ -0,0 +1,92 @@
+{
+    "ports" : {
+        "device:bmv2:204/3" : {
+            "interfaces" : [
+                {
+                    "name": "h1",
+                    "ips" : [ "10.0.10.254/24" ],
+                    "vlan-untagged": 10
+                }
+            ]
+        },
+        "device:bmv2:204/4" : {
+            "interfaces" : [
+                {
+                    "name": "h2",
+                    "ips" : [ "10.0.10.254/24" ],
+                    "vlan-untagged": 10
+                }
+            ]
+        },
+        "device:bmv2:205/3" : {
+            "interfaces" : [
+                {
+                    "name": "h3",
+                    "ips" : [ "10.0.20.254/24" ],
+                    "vlan-untagged": 20
+                }
+            ]
+        },
+        "device:bmv2:205/4" : {
+            "interfaces" : [
+                {
+                    "name": "h4",
+                    "ips" : [ "10.0.20.254/24" ],
+                    "vlan-untagged": 20
+                }
+            ]
+        }
+    },
+    "devices" : {
+        "device:bmv2:204" : {
+            "segmentrouting" : {
+                "name" : "s204",
+                "ipv4NodeSid" : 204,
+                "ipv4Loopback" : "192.168.0.204",
+                "ipv6NodeSid" : 214,
+                "ipv6Loopback" : "2000::c0a8:0204",
+                "routerMac" : "00:00:00:00:02:04",
+                "isEdgeRouter" : true,
+                "adjacencySids" : []
+            }
+        },
+        "device:bmv2:205" : {
+            "segmentrouting" : {
+                "name" : "s205",
+                "ipv4NodeSid" : 205,
+                "ipv4Loopback" : "192.168.0.205",
+                "ipv6NodeSid" : 215,
+                "ipv6Loopback" : "2000::c0a8:0205",
+                "routerMac" : "00:00:00:00:02:05",
+                "isEdgeRouter" : true,
+                "adjacencySids" : []
+            }
+        },
+        "device:bmv2:226" : {
+            "segmentrouting" : {
+                "name" : "s226",
+                "ipv4NodeSid" : 226,
+                "ipv4Loopback" : "192.168.0.226",
+                "ipv6NodeSid" : 236,
+                "ipv6Loopback" : "2000::c0a8:0226",
+                "routerMac" : "00:00:00:00:02:26",
+                "isEdgeRouter" : false,
+                "adjacencySids" : []
+            }
+        },
+        "device:bmv2:227" : {
+            "segmentrouting" : {
+                "name" : "s227",
+                "ipv4NodeSid" : 227,
+                "ipv4Loopback" : "192.168.0.227",
+                "ipv6NodeSid" : 237,
+                "ipv6Loopback" : "2000::c0a8:0227",
+                "routerMac" : "00:00:00:00:02:27",
+                "isEdgeRouter" : false,
+                "adjacencySids" : []
+            }
+        }
+    },
+    "apps" : {
+    }
+}
diff --git a/trellis/trellisp4.py b/trellis/trellisp4.py
new file mode 100755
index 0000000..7f8f82a
--- /dev/null
+++ b/trellis/trellisp4.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+import os
+import sys
+import argparse
+sys.path.append('..')
+
+if 'ONOS_ROOT' not in os.environ:
+    print "Environment var $ONOS_ROOT not set"
+    exit()
+else:
+    ONOS_ROOT = os.environ["ONOS_ROOT"]
+    sys.path.append(ONOS_ROOT + "/tools/dev/mininet")
+
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.node import Host, RemoteController
+from routinglib import RoutedHost
+from bmv2 import ONOSBmv2Switch
+
+PIPECONF_ID = 'org.onosproject.pipelines.fabric'
+
+class Trellis( Topo ):
+    "Trellis basic topology"
+
+    def __init__( self, *args, **kwargs ):
+        Topo.__init__( self, *args, **kwargs )
+
+        # Spines
+        s226 = self.addSwitch('s226', cls=ONOSBmv2Switch, deviceId='226', grpcPort=55226, pipeconfId=PIPECONF_ID, netcfgDelay=0.5)
+        s227 = self.addSwitch('s227', cls=ONOSBmv2Switch, deviceId='227', grpcPort=55227, pipeconfId=PIPECONF_ID, netcfgDelay=0.5)
+
+        # Leaves
+        s204 = self.addSwitch('s204', cls=ONOSBmv2Switch, deviceId='204', grpcPort=55204, pipeconfId=PIPECONF_ID, netcfgDelay=0.5)
+        s205 = self.addSwitch('s205', cls=ONOSBmv2Switch, deviceId='205', grpcPort=55205, pipeconfId=PIPECONF_ID, netcfgDelay=0.5)
+
+        # Switch Links
+        self.addLink(s226, s204)
+        self.addLink(s226, s205)
+        self.addLink(s227, s204)
+        self.addLink(s227, s205)
+
+        # NOTE avoid using 10.0.1.0/24 which is the default subnet of quaggas
+        # NOTE avoid using 00:00:00:00:00:xx which is the default mac of host behind upstream router
+        # IPv4 Hosts
+        h1 = self.addHost('h1', cls=RoutedHost, mac='00:aa:00:00:00:01', ips=['10.0.10.1/24'], gateway='10.0.10.254')
+        h2 = self.addHost('h2', cls=RoutedHost, mac='00:aa:00:00:00:02', ips=['10.0.10.2/24'], gateway='10.0.10.254')
+        h3 = self.addHost('h3', cls=RoutedHost, mac='00:aa:00:00:00:03', ips=['10.0.20.1/24'], gateway='10.0.20.254')
+        h4 = self.addHost('h4', cls=RoutedHost, mac='00:aa:00:00:00:04', ips=['10.0.20.2/24'], gateway='10.0.20.254')
+        self.addLink(h1, s204)
+        self.addLink(h2, s204)
+        self.addLink(h3, s205)
+        self.addLink(h4, s205)
+
+topos = { 'trellis' : Trellis }
+
+def main(args):
+    topo = Trellis()
+    controller = RemoteController('c0', ip=args.onos_ip)
+
+    net = Mininet(topo=topo, controller=None)
+    net.addController(controller)
+
+    net.start()
+    CLI(net)
+    net.stop()
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(
+        description='BMv2 mininet demo script (2 by 2 fabric)')
+    parser.add_argument('--onos-ip', help='ONOS-BMv2 controller IP address',
+                        type=str, action="store", required=True)
+    args = parser.parse_args()
+    setLogLevel('debug')
+
+    main(args)