Version 7 (modified by 14 years ago) ( diff ) | ,
---|
NOX - Network OS
NOX is an OpenFlow controller/ controller development platform. Here we'll use the "destiny" (v0.8) branch of NOX from the Git repository. As of now, a copy of the docs for v0.6 can be found under ./html in my home directory on external2. I shall move this to another, more appropriate place.
Note: in this documentation, ${NOXPATH} is the arbitrary path to your working nox directory. No such variable actually exists.
1 installation
- Install git, build-essential, doxygen (for up-to-date NOX docs)
apt-get install git-core build-essential doxygen
- Pull NOX from git repo
cd ${noxpath} git clone git://noxrepo.org/nox
- Install dependencies
sudo apt-get install autoconf automake g++ libtool python python-twisted swig libboost-dev libxerces-c2-dev libssl-dev make libboost-filesystem-dev libboost-test-dev python-dev
- Switch to the proper branch and build
git checkout -b destiny origin/destiny ./boot.sh mkdir build cd build ../configure make
- generate documentation
cd doc/doxygen <<--from build directory, not ${NOXPATH}/nox make html
2. using NOX
2.1. starting up NOX
nox_core is used to start the controller and to load any scripts. It is located under ${NOXPATH}/nox/build/src . For example
./nox_core -v -i ptcp:6633 switch packetdump
Will load the "learning switch" script. It will show up as "lt-nox_core" under ps -ef
.
2.2. creating a component (in C++)
The information on how to do this can be found in /html/Howto.html under the doxygen generated docs for nox. As the steps require file creation, compilation, ect, you may need root privelages on the machine. The rough steps are as follows:
- Run nox-new-c-app.py from coreapps, netapps, or webapps (all three directories are found in ${NOXPATH}/nox/src/nox ).
cd nox/src/nox/coreapps /home/openflow/nox/src/scripts/nox-new-c-app.py -v cnf_test
nox-new-c-app.py basically creates a directory containing the framework for your application (Makefile, meta.json, ect), basing it on coreapps/simple_c_app. Your app gets created in whichever directory you run nox-new-c-app.py from; in this case we created a new app "cnf_test" in directory coreapps.
- run
boot.sh
andconfigure
so nox can find and load the app when it starts up:./boot.sh #this is found in the root of your nox directory e.g. ${NOXPATH}/nox/boot.sh cd build ../configure make
- to test if your app is there, you can watch out for it being loaded when you do a dry run of nox_core:
root@node1-4:~/nox/build/src# ./nox_core -i ptcp:6633 -v 00001|nox|INFO:Starting nox_core (/home/openflow/nox/build/src/.libs/lt-nox_core) ... 00006|pyrt|DBG:Loading a component description file 'nox/coreapps/cnf_test/meta.json'.
or try loading it:
./nox_core -i ptcp:6633 -v "cnf test"
note that any underscores in the name of your app become spaces - e.g. "cnf_test" becomes "cnf test"
If you see the following after issuing the above command, you have a working framework:
00046|openflow|DBG:Passive tcp interface bound to port 6633 00047|nox|INFO:nox bootstrap complete 00048|openflow|DBG:Passive tcp interface received connection 00049|openflow|DBG:stream: negotiated OpenFlow version 0x01 (we support versions 0x01 to 0x01 inclusive, peer no later than version 0x01) ...
3. Customizing your component
All applications under nox are found in either netapps., coreapps, or webapps. Each app is contained in a directory that includes code for the applications' modules (e.g. routing modules implementing specific algorithms), and a list, named meta.json, used by nox to find and load modules at startup.
By itself, your new component only knows how to initiate a channel with an OpenFlow switch, and to start up the "liveness check" echo requests. This section is a compilation of information on the nox libraries that can be used to define your own controller.
3.1 The configure function.
The configure
function allows you to register the events that the module will respond to via the Disposition
type function (more detail later on regarding this), and to define options for your application.
3.1.1. starting modules with flags
When starting nox_core, flags can be specified by the application name, followed by an '=', then your flag(s):
./nox_core -v -i ptcp:6633 switch="noflow"
I'm guessing if it can take multiple options, you can string multiple flags by delimiting each option with a comma or another '='.
3.1.2. registering events.
This is done with the register_handler
which takes your event's name and allows you to specify a NOX event to bind to it:
register_handler<Flow_in_event> (boost::bind(&SPRouting::handle_flow_in, this, _1));
Here, a Flow_in_event (defined in NOX libraries) is taken as an argument to the module specific Disposition type function handle_flow_in
.
This snippet is taken from the built-in routing module (netapps/routing/sprouting.cc, .hh) which makes an OF switch behave like a router. The sprouting module is fairly complex and can be used to see how a module is built; we'll be using pieces of this module (along with others where specified) throughout this page.
3.1.3. defining flags/options.
It seems customary to define and check for flags within configure function, but this doesn't have to be the case. For example, in sprouting, there is a separate function called validate_args
.
A more "traditional" way of doing this is through the Configuration object (found in nox/src/nox/component.hh):
class Configuration { public: virtual ~Configuration(); /* Retrieve a value of an XML configuration key. */ virtual const std::string get(const std::string& key) const = 0; /* Return true if the XML key exists. */ virtual const bool has(const std::string& key) const = 0; /* Return all XML keys. */ virtual const std::list<std::string> keys() const = 0; /* Return all command line arguments of the component. */ virtual const Component_argument_list get_arguments() const = 0; /* Return list of arguments. */ virtual const hash_map<std::string, std::string> get_arguments_list(char d1 = ',', char d2 = '=') const = 0; };
This class allows you to input flags as described earlier in 3.1.1. Actually using the class involves something like this (from switch.cc).
Switch::configure(const Configuration* conf) { ... BOOST_FOREACH (const std::string& arg, conf->get_arguments()) { if (arg == "noflow") { setup_flows = false; } else { VLOG_WARN(log, "argument \"%s\" not supported", arg.c_str()); } } ...
3.2. Event triggers
3.2.1 The Disposition type