First commit
diff --git a/util/nox-patches/0001-OpenFlow-tutorial-port-nox-destiny.patch b/util/nox-patches/0001-OpenFlow-tutorial-port-nox-destiny.patch
new file mode 100644
index 0000000..881fc55
--- /dev/null
+++ b/util/nox-patches/0001-OpenFlow-tutorial-port-nox-destiny.patch
@@ -0,0 +1,298 @@
+From 5c9610ffb88c89b0f36359ad3c7547831482a3ff Mon Sep 17 00:00:00 2001
+From: Bob Lantz <rlantz@cs.stanford.edu>
+Date: Fri, 3 Feb 2012 14:48:58 -0800
+Subject: [PATCH] OpenFlow tutorial port nox-destiny.
+
+---
+ src/nox/coreapps/examples/Makefile.am | 2 +-
+ src/nox/coreapps/examples/tutorial/Makefile.am | 25 ++++
+ src/nox/coreapps/examples/tutorial/meta.json | 12 ++
+ src/nox/coreapps/examples/tutorial/pytutorial.py | 67 +++++++++++
+ src/nox/coreapps/examples/tutorial/tutorial.cc | 134 ++++++++++++++++++++++
+ 5 files changed, 239 insertions(+), 1 deletions(-)
+ create mode 100644 src/nox/coreapps/examples/tutorial/Makefile.am
+ create mode 100644 src/nox/coreapps/examples/tutorial/__init__.py
+ create mode 100644 src/nox/coreapps/examples/tutorial/meta.json
+ create mode 100644 src/nox/coreapps/examples/tutorial/pytutorial.py
+ create mode 100644 src/nox/coreapps/examples/tutorial/tutorial.cc
+
+diff --git a/src/nox/coreapps/examples/Makefile.am b/src/nox/coreapps/examples/Makefile.am
+index 126f32e..1a0458c 100644
+--- a/src/nox/coreapps/examples/Makefile.am
++++ b/src/nox/coreapps/examples/Makefile.am
+@@ -1,6 +1,6 @@
+ include ../../../Make.vars
+
+-SUBDIRS = t
++SUBDIRS = tutorial t
+
+ EXTRA_DIST =\
+ meta.json\
+diff --git a/src/nox/coreapps/examples/tutorial/Makefile.am b/src/nox/coreapps/examples/tutorial/Makefile.am
+new file mode 100644
+index 0000000..51cf921
+--- /dev/null
++++ b/src/nox/coreapps/examples/tutorial/Makefile.am
+@@ -0,0 +1,25 @@
++include ../../../../Make.vars
++
++EXTRA_DIST =\
++ meta.xml \
++ __init__.py \
++ pytutorial.py
++
++if PY_ENABLED
++AM_CPPFLAGS += $(PYTHON_CPPFLAGS)
++endif # PY_ENABLED
++
++pkglib_LTLIBRARIES = \
++ tutorial.la
++
++tutorial_la_CPPFLAGS = $(AM_CPPFLAGS) -I $(top_srcdir)/src/nox -I $(top_srcdir)/src/nox/coreapps/
++tutorial_la_SOURCES = tutorial.cc
++tutorial_la_LDFLAGS = -module -export-dynamic
++
++NOX_RUNTIMEFILES = meta.json \
++ __init__.py \
++ pytutorial.py
++
++all-local: nox-all-local
++clean-local: nox-clean-local
++install-exec-hook: nox-install-local
+diff --git a/src/nox/coreapps/examples/tutorial/__init__.py b/src/nox/coreapps/examples/tutorial/__init__.py
+new file mode 100644
+index 0000000..e69de29
+diff --git a/src/nox/coreapps/examples/tutorial/meta.json b/src/nox/coreapps/examples/tutorial/meta.json
+new file mode 100644
+index 0000000..7a9f227
+--- /dev/null
++++ b/src/nox/coreapps/examples/tutorial/meta.json
+@@ -0,0 +1,12 @@
++{
++ "components": [
++ {
++ "name": "tutorial",
++ "library": "tutorial"
++ },
++ {
++ "name": "pytutorial",
++ "python": "nox.coreapps.examples.tutorial.pytutorial"
++ }
++ ]
++}
+diff --git a/src/nox/coreapps/examples/tutorial/pytutorial.py b/src/nox/coreapps/examples/tutorial/pytutorial.py
+new file mode 100644
+index 0000000..1e21c0b
+--- /dev/null
++++ b/src/nox/coreapps/examples/tutorial/pytutorial.py
+@@ -0,0 +1,67 @@
++# Tutorial Controller
++# Starts as a hub, and your job is to turn this into a learning switch.
++
++import logging
++
++from nox.lib.core import *
++import nox.lib.openflow as openflow
++from nox.lib.packet.ethernet import ethernet
++from nox.lib.packet.packet_utils import mac_to_str, mac_to_int
++
++log = logging.getLogger('nox.coreapps.tutorial.pytutorial')
++
++
++class pytutorial(Component):
++
++ def __init__(self, ctxt):
++ Component.__init__(self, ctxt)
++ # Use this table to store MAC addresses in the format of your choice;
++ # Functions already imported, including mac_to_str, and mac_to_int,
++ # should prove useful for converting the byte array provided by NOX
++ # for packet MAC destination fields.
++ # This table is initialized to empty when your module starts up.
++ self.mac_to_port = {} # key: MAC addr; value: port
++
++ def learn_and_forward(self, dpid, inport, packet, buf, bufid):
++ """Learn MAC src port mapping, then flood or send unicast."""
++
++ # Initial hub behavior: flood packet out everything but input port.
++ # Comment out the line below when starting the exercise.
++ self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
++
++ # Starter psuedocode for learning switch exercise below: you'll need to
++ # replace each pseudocode line with more specific Python code.
++
++ # Learn the port for the source MAC
++ #self.mac_to_port = <fill in>
++ #if (destination MAC of the packet is known):
++ # Send unicast packet to known output port
++ #self.send_openflow( <fill in params> )
++ # Later, only after learning controller works:
++ # push down flow entry and remove the send_openflow command above.
++ #self.install_datapath_flow( <fill in params> )
++ #else:
++ #flood packet out everything but the input port
++ #self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
++
++ def packet_in_callback(self, dpid, inport, reason, len, bufid, packet):
++ """Packet-in handler"""
++ if not packet.parsed:
++ log.debug('Ignoring incomplete packet')
++ else:
++ self.learn_and_forward(dpid, inport, packet, packet.arr, bufid)
++
++ return CONTINUE
++
++ def install(self):
++ self.register_for_packet_in(self.packet_in_callback)
++
++ def getInterface(self):
++ return str(pytutorial)
++
++def getFactory():
++ class Factory:
++ def instance(self, ctxt):
++ return pytutorial(ctxt)
++
++ return Factory()
+diff --git a/src/nox/coreapps/examples/tutorial/tutorial.cc b/src/nox/coreapps/examples/tutorial/tutorial.cc
+new file mode 100644
+index 0000000..e7240cc
+--- /dev/null
++++ b/src/nox/coreapps/examples/tutorial/tutorial.cc
+@@ -0,0 +1,134 @@
++#include "component.hh"
++#include "config.h"
++#include "packet-in.hh"
++#include "flow.hh"
++#include "assert.hh"
++#include "netinet++/ethernetaddr.hh"
++#include "netinet++/ethernet.hh"
++#include <boost/shared_array.hpp>
++#include <boost/bind.hpp>
++#ifdef LOG4CXX_ENABLED
++#include <boost/format.hpp>
++#include "log4cxx/logger.h"
++#else
++#include "vlog.hh"
++#endif
++
++using namespace std;
++using namespace vigil;
++using namespace vigil::container;
++
++namespace
++{
++ static Vlog_module lg("tutorial");
++
++ /** Learning switch.
++ */
++ class tutorial
++ : public Component
++ {
++ public:
++ /** Constructor.
++ */
++ tutorial(const Context* c, const json_object* node)
++ : Component(c)
++ { }
++
++ /** Configuration.
++ * Add handler for packet-in event.
++ */
++ void configure(const Configuration*)
++ {
++ register_handler<Packet_in_event>
++ (boost::bind(&tutorial::handle, this, _1));
++ }
++
++ /** Just simply install.
++ */
++ void install()
++ {
++ lg.dbg(" Install called ");
++ }
++
++ /** Function to setup flow.
++ */
++ void setup_flow(Flow& flow, datapathid datapath_id ,
++ uint32_t buffer_id, uint16_t out_port)
++ {
++ ofp_flow_mod* ofm;
++ size_t size = sizeof *ofm + sizeof(ofp_action_output);
++ boost::shared_array<char> raw_of(new char[size]);
++ ofm = (ofp_flow_mod*) raw_of.get();
++
++ ofm->header.version = OFP_VERSION;
++ ofm->header.type = OFPT_FLOW_MOD;
++ ofm->header.length = htons(size);
++ ofm->match.wildcards = htonl(0);
++ ofm->match.in_port = htons(flow.in_port);
++ ofm->match.dl_vlan = flow.dl_vlan;
++ memcpy(ofm->match.dl_src, flow.dl_src.octet, sizeof ofm->match.dl_src);
++ memcpy(ofm->match.dl_dst, flow.dl_dst.octet, sizeof ofm->match.dl_dst);
++ ofm->match.dl_type = flow.dl_type;
++ ofm->match.nw_src = flow.nw_src;
++ ofm->match.nw_dst = flow.nw_dst;
++ ofm->match.nw_proto = flow.nw_proto;
++ ofm->match.tp_src = flow.tp_src;
++ ofm->match.tp_dst = flow.tp_dst;
++ ofm->command = htons(OFPFC_ADD);
++ ofm->buffer_id = htonl(buffer_id);
++ ofm->idle_timeout = htons(5);
++ ofm->hard_timeout = htons(OFP_FLOW_PERMANENT);
++ ofm->priority = htons(OFP_DEFAULT_PRIORITY);
++ ofp_action_output& action = *((ofp_action_output*)ofm->actions);
++ memset(&action, 0, sizeof(ofp_action_output));
++ action.type = htons(OFPAT_OUTPUT);
++ action.len = htons(sizeof(ofp_action_output));
++ action.max_len = htons(0);
++ action.port = htons(out_port);
++ send_openflow_command(datapath_id, &ofm->header, true);
++ }
++
++ /** Function to handle packets.
++ * @param datapath_id datapath id of switch
++ * @param in_port port packet is received
++ * @param buffer_id buffer id of packet
++ * @param source source mac address in host order
++ * @param destination destination mac address in host order
++ */
++ void handle_packet(datapathid datapath_id, uint16_t in_port, uint32_t buffer_id,
++ uint64_t source, uint64_t destination)
++ {
++ send_openflow_packet(datapath_id, buffer_id, OFPP_FLOOD,
++ in_port, true);
++ }
++
++ /** Packet-on handler.
++ */
++ Disposition handle(const Event& e)
++ {
++ const Packet_in_event& pi = assert_cast<const Packet_in_event&>(e);
++ uint32_t buffer_id = pi.buffer_id;
++ Flow flow(pi.in_port, *pi.get_buffer());
++
++ // drop LLDP packets
++ if (flow.dl_type == ethernet::LLDP)
++ return CONTINUE;
++
++ // pass handle of unicast packet, else flood
++ if (!flow.dl_src.is_multicast())
++ handle_packet(pi.datapath_id, pi.in_port, buffer_id,
++ flow.dl_src.hb_long(), flow.dl_dst.hb_long());
++ else
++ send_openflow_packet(pi.datapath_id, buffer_id, OFPP_FLOOD,
++ pi.in_port, true);
++
++ return CONTINUE;
++ }
++
++ private:
++};
++
++REGISTER_COMPONENT(container::Simple_component_factory<tutorial>,
++ tutorial);
++
++} // unnamed namespace
+--
+1.7.5.4
+
diff --git a/util/nox-patches/0002-nox-ubuntu12-hacks.patch b/util/nox-patches/0002-nox-ubuntu12-hacks.patch
new file mode 100644
index 0000000..77619bc
--- /dev/null
+++ b/util/nox-patches/0002-nox-ubuntu12-hacks.patch
@@ -0,0 +1,175 @@
+From 166693d7cb640d4a41251b87e92c52d9c688196b Mon Sep 17 00:00:00 2001
+From: Bob Lantz <rlantz@cs.stanford.edu>
+Date: Mon, 14 May 2012 15:30:44 -0700
+Subject: [PATCH] Hacks to get NOX classic/destiny to compile under Ubuntu
+ 12.04
+
+Thanks to Srinivasu R. Kanduru for the initial patch.
+
+Apologies for the hacks - it is my hope that this will be fixed
+upstream eventually.
+
+---
+ config/ac_pkg_swig.m4 | 7 ++++---
+ src/Make.vars | 2 +-
+ src/nox/coreapps/pyrt/deferredcallback.cc | 2 +-
+ src/nox/coreapps/pyrt/pyglue.cc | 2 +-
+ src/nox/coreapps/pyrt/pyrt.cc | 2 +-
+ src/nox/netapps/authenticator/auth.i | 2 ++
+ src/nox/netapps/authenticator/flow_util.i | 1 +
+ src/nox/netapps/routing/routing.i | 2 ++
+ .../switch_management/pyswitch_management.i | 2 ++
+ src/nox/netapps/tests/tests.cc | 2 +-
+ src/nox/netapps/topology/pytopology.i | 2 ++
+ 11 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/config/ac_pkg_swig.m4 b/config/ac_pkg_swig.m4
+index d12556e..9b608f2 100644
+--- a/config/ac_pkg_swig.m4
++++ b/config/ac_pkg_swig.m4
+@@ -78,9 +78,10 @@ AC_DEFUN([AC_PROG_SWIG],[
+ if test -z "$available_patch" ; then
+ [available_patch=0]
+ fi
+- if test $available_major -ne $required_major \
+- -o $available_minor -ne $required_minor \
+- -o $available_patch -lt $required_patch ; then
++ major_done=`test $available_major -gt $required_major`
++ minor_done=`test $available_minor -gt $required_minor`
++ if test !$major_done -a !$minor_done \
++ -a $available_patch -lt $required_patch ; then
+ AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
+ SWIG=''
+ else
+diff --git a/src/Make.vars b/src/Make.vars
+index d70d6aa..93b2879 100644
+--- a/src/Make.vars
++++ b/src/Make.vars
+@@ -53,7 +53,7 @@ AM_LDFLAGS += -export-dynamic
+ endif
+
+ # set python runtimefiles to be installed in the same directory as pkg
+-pkglib_SCRIPTS = $(NOX_RUNTIMEFILES) $(NOX_PYBUILDFILES)
++pkgdata_SCRIPTS = $(NOX_RUNTIMEFILES) $(NOX_PYBUILDFILES)
+ BUILT_SOURCES = $(NOX_PYBUILDFILES)
+
+ # Runtime-files build and clean rules
+diff --git a/src/nox/coreapps/pyrt/deferredcallback.cc b/src/nox/coreapps/pyrt/deferredcallback.cc
+index 3a40fa7..111a586 100644
+--- a/src/nox/coreapps/pyrt/deferredcallback.cc
++++ b/src/nox/coreapps/pyrt/deferredcallback.cc
+@@ -69,7 +69,7 @@ DeferredCallback::get_instance(const Callback& c)
+ DeferredCallback* cb = new DeferredCallback(c);
+
+ // flag as used in *_wrap.cc....correct?
+- return SWIG_Python_NewPointerObj(cb, s, SWIG_POINTER_OWN | 0);
++ return SWIG_Python_NewPointerObj(m, cb, s, SWIG_POINTER_OWN | 0);
+ }
+
+ bool
+diff --git a/src/nox/coreapps/pyrt/pyglue.cc b/src/nox/coreapps/pyrt/pyglue.cc
+index 48b9716..317fd04 100644
+--- a/src/nox/coreapps/pyrt/pyglue.cc
++++ b/src/nox/coreapps/pyrt/pyglue.cc
+@@ -874,7 +874,7 @@ to_python(const Flow& flow)
+ if (!s) {
+ throw std::runtime_error("Could not find Flow SWIG type_info");
+ }
+- return SWIG_Python_NewPointerObj(f, s, SWIG_POINTER_OWN | 0);
++ return SWIG_Python_NewPointerObj(m, f, s, SWIG_POINTER_OWN | 0);
+
+ // PyObject* dict = PyDict_New();
+ // if (!dict) {
+diff --git a/src/nox/coreapps/pyrt/pyrt.cc b/src/nox/coreapps/pyrt/pyrt.cc
+index fbda461..8ec05d6 100644
+--- a/src/nox/coreapps/pyrt/pyrt.cc
++++ b/src/nox/coreapps/pyrt/pyrt.cc
+@@ -776,7 +776,7 @@ Python_event_manager::create_python_context(const Context* ctxt,
+ pretty_print_python_exception());
+ }
+
+- PyObject* pyctxt = SWIG_Python_NewPointerObj(p, s, 0);
++ PyObject* pyctxt = SWIG_Python_NewPointerObj(m, p, s, 0);
+ Py_INCREF(pyctxt); // XXX needed?
+
+ //Py_DECREF(m);
+diff --git a/src/nox/netapps/authenticator/auth.i b/src/nox/netapps/authenticator/auth.i
+index 1de1a17..bfa04e2 100644
+--- a/src/nox/netapps/authenticator/auth.i
++++ b/src/nox/netapps/authenticator/auth.i
+@@ -18,6 +18,8 @@
+
+ %module "nox.netapps.authenticator.pyauth"
+
++// Hack to get it to compile -BL
++%include "std_list.i"
+ %{
+ #include "core_events.hh"
+ #include "pyrt/pycontext.hh"
+diff --git a/src/nox/netapps/authenticator/flow_util.i b/src/nox/netapps/authenticator/flow_util.i
+index f67c3ef..2a314e2 100644
+--- a/src/nox/netapps/authenticator/flow_util.i
++++ b/src/nox/netapps/authenticator/flow_util.i
+@@ -32,6 +32,7 @@ using namespace vigil::applications;
+ %}
+
+ %include "common-defs.i"
++%include "std_list.i"
+
+ %import "netinet/netinet.i"
+ %import "pyrt/event.i"
+diff --git a/src/nox/netapps/routing/routing.i b/src/nox/netapps/routing/routing.i
+index 44ccb3d..f9221a2 100644
+--- a/src/nox/netapps/routing/routing.i
++++ b/src/nox/netapps/routing/routing.i
+@@ -17,6 +17,8 @@
+ */
+ %module "nox.netapps.routing.pyrouting"
+
++// Hack to get it to compile -BL
++%include "std_list.i"
+ %{
+ #include "pyrouting.hh"
+ #include "routing.hh"
+diff --git a/src/nox/netapps/switch_management/pyswitch_management.i b/src/nox/netapps/switch_management/pyswitch_management.i
+index 72bfed4..ad2c90d 100644
+--- a/src/nox/netapps/switch_management/pyswitch_management.i
++++ b/src/nox/netapps/switch_management/pyswitch_management.i
+@@ -18,6 +18,8 @@
+
+ %module "nox.netapps.pyswitch_management"
+
++// Hack to get it to compile -BL
++%include "std_list.i"
+ %{
+ #include "switch_management_proxy.hh"
+ #include "pyrt/pycontext.hh"
+diff --git a/src/nox/netapps/tests/tests.cc b/src/nox/netapps/tests/tests.cc
+index 20e900d..f027028 100644
+--- a/src/nox/netapps/tests/tests.cc
++++ b/src/nox/netapps/tests/tests.cc
+@@ -306,7 +306,7 @@ private:
+ throw runtime_error("Could not find PyContext SWIG type_info.");
+ }
+
+- PyObject* pyctxt = SWIG_Python_NewPointerObj(p, s, 0);
++ PyObject* pyctxt = SWIG_Python_NewPointerObj(m, p, s, 0);
+ assert(pyctxt);
+
+ Py_DECREF(m);
+diff --git a/src/nox/netapps/topology/pytopology.i b/src/nox/netapps/topology/pytopology.i
+index 94a9f4b..7a8cd94 100644
+--- a/src/nox/netapps/topology/pytopology.i
++++ b/src/nox/netapps/topology/pytopology.i
+@@ -18,6 +18,8 @@
+
+ %module "nox.netapps.topology"
+
++// Hack to get it to compile -BL
++%include "std_list.i"
+ %{
+ #include "pytopology.hh"
+ #include "pyrt/pycontext.hh"
+--
+1.7.5.4
+
diff --git a/util/nox-patches/README b/util/nox-patches/README
new file mode 100644
index 0000000..b74a668
--- /dev/null
+++ b/util/nox-patches/README
@@ -0,0 +1,2 @@
+0001: This patch adds the OpenFlow tutorial module source code to nox-destiny.
+0002: This patch hacks nox-destiny to compile on Ubuntu 12.04.