This section provides a brief primer to developing applications on NOX. Unfortunately there currently isn’t extensive API documentation so you should expect to get comfortable with the source.
NOX applications interact with the network in two ways:
At their most basic, therefore, NOX applications are really just a set of event handlers which are called on particular network events.
NOX applications can be written in either C++ or Python (or both). At the time of this writing, the Python API to the network is more mature and therefore more friendly for new NOX developers. We recommend that unless the application being developed has serious performance requirements, that developers start with Python.
All NOX application code resides in src/nox/apps/. In general, each NOX application has its own directory within src/nox/apps/ however this isn’t strictly necessary (for example src/nox/apps/examples/ contains multiple apps).
Create a directory in srx/nox/apps/ (lets call it foo)
copy from src/nox/apps/simple_cc_app
- Makefile.am
- simple_cc_app.cc → foo_app.cc
- meta.xml
Edit Makefile.am and meta.xml to use foo* instead of simple_c*
Edit foo_app.cc to taste (rename class SimpleCCApp to FooApp)
Modify ($NOXDIR)/configure.ac in three places (try searching for “simple_c_app”)
- Add a new ACI_MODULE entry for foo.
- Add foo to the list in the “main source library” ACI_MODULE entry.
- add src/nox/apps/foo/Makefile to the AC_CONFIG_FILES variable.
Rebuild using ‘make’
Test by running. Command line should be something like:
./nox_core foo
Note that if you used a space in the app name in meta.xml, you’ll need to surround it with quotes .. e.g. “foo app”
Warning
configur.ac is currently a mess. This should be cleaned up in subsequent releases.
Inter-App dependencies
If your app depends on another app (for example, topology relies on discovery), you’ll want to add the dependency to meta.xml in the app directory. Dependencies are added with a dependency tag within the component tag. For example:
<component>
<name>foo</name>
<library>foo.so</library>
<dependency><name>network database</name></dependency>
</component>
To get a handle to another application in your code, use the resolve method (inherited by your app class from Component). Say you want to get a pointer to the topology component. Then the call should look something like:
Topology* topology; resolve(topology); // resolve inherited from Component
Ordering for packet processing goes in etc/nox.xml. If there is a specific order in which you app handles an event in relation to another component, add the component(s) to the event in the order they are meant to handle it.
Pointers
The core system API is in nox/lib/core.py.
To get a handle to another component, use the Component.resolve(..) method on the class or interface to which you want a handle. For example:
from nox.app.examples.pyswitch import pyswitch
self.resolve(pyswitch)
Integrated components (those exposed to both C++ and Python) are really composed of two components. The C++ component (built like any other C++ component) and a Python component which acts as a proxy for the C++ component in Python. src/nox/apps/simple-c-py-app/ contains an example of how to do this.
Subtleties
If the interface you expose to Python has any “non-basic” types in the function signature, you may need to %include additional .i files to define those type. Examples of “non-basic” types include “string” or “uint32_t”. For example:
%include "std_string.i" %include "../../lib/common-defs.i"
The Python component must be a class which inherits from Component (like any other python component). See src/nox/apps/simple_c_py_app/pysimple_c_py_app.i as an example of how to do this.
Creating the Makefile.am for these components is really messy. This will be cleaned up and pushed into make.vars at some point.