Efficient Synthesis of Network Updates

Downloads

There is alternatively a 32bit VM, but we don't recommend it (2.7 GB): netsynth32.ova.
There is a binaries+source ZIP equivalent of the tarball (41.5 MB): netsynth.zip.
Backup mirrors: paper.pdf, paper.pdf, netsynth64.ova, netsynth32.ova, netsynth.tgz, netsynth.zip.

AEC Conflicts

Our Experimental Platform:

We recommend using a 64bit host machine with at least 2+ processors and 8+ GB RAM.

Installation (Three Options):

  1. Use the Virtual Machine image with all tools installed (difficulty: easy)
    1. Download a VM image (preferably 64bit).
    2. Start VirtualBox on your host machine.
    3. Select "File" -> "Import Appliance", and select the downloaded image.
    4. If possible, give the VM more memory/processors to more closely match our baseline machine.
    5. You may need to turn on virtualization extensions in your BIOS to enable 64bit virtualization.
    6. Upon VM startup, the "netsynth" user should be logged in (username: netsynth, password: netsynth).
    7. Open a terminal and navigate to the ~/tools/netsynth directory.

  2. Use the pre-built Ubuntu binaries (difficulty: medium)
    1. Download the tarball (or ZIP) onto an Ubuntu (preferably 14.04.1) machine.
    2. Extract tarball and install the binaries for your platform (either i686 or x86_64, but again, we recommend using an x86_64 machine):
      PLATFORM=`uname -i`
      tar -xvf netsynth.tgz
      cd netsynth
      tar -xvf yices-1.0.39-$PLATFORM-pc-linux-gnu.tar.gz
      cd yices-1.0.39
      chmod +rx bin/yices
      chmod +rx lib/libyices.so
      sudo cp -rv * /usr
      cd ..
      sudo apt-get install -y liblog4cxx10-dev libcppunit-dev graphviz python-networkx mininet
      cp $PLATFORM/netsynth .
      sudo cp $PLATFORM/net_plumber $PLATFORM/NuSMV /usr/bin
    3. At this point, you should be able to type ./netsynth help and see a usage message.
    4. Finally, build the experiments:
      cd experiments
      make
      cd ..
  3. Build the tools from source (difficulty: hard)
    1. Be warned that this may change your existing OCaml installation! Thus we recommend that you start with a fresh Ubuntu 14.04.1 installation (or at least one that doesn't already have OCaml installed).
    2. Download the tarball (or ZIP).
    3. Extract tarball and try to run the install script (it should automatically detect your platform (i686 or x86_64), but again, we recommend using an x86_64 machine):
      tar -xvf netsynth.tgz
      cd netsynth
      ./install_ubuntu.sh
    4. If any step of the installation fails, you will need to manually perform the installation steps to pinpoint the problem. The install script install_ubuntu.sh is fairly well-documented to assist with this.
    5. If all goes well, you should be able to type ./netsynth and see a usage message, and typing
      which net_plumber NuSMV yices
      should show all three of these tools as being installed.

Basic Tool Usage:

  1. Getting basic help about command-line usage of Netsynth:
    ./netsynth help
  2. Invoking Netsynth functionality in general:
    ./netsynth <command> [options]
    Note that commands can be abbreviated:
    ./netsynth help
    ./netsynth he
    ./netsynth h
    To get a list of options for a certain command:
    ./netsynth help <command>
  3. The most basic command is solve, which solves a pre-defined network update problem instance. These are stored as .ltl files, and encode the topology, initial/final configuration, and linear temporal logic (LTL) property in a human-readable format:
    ./netsynth solve code/examples/diamond.ltl

    The output is an SDN program, represented as a sequence of controller commands, each of which is either update (represented as (s,r) where s is a switch ID, and r is a rule index) or wait (represented as #). A negative rule index is used to denote an atomic update of all rules on that switch (i.e. a switch-granularity update).

    To view only the synthesized SDN program, grep for a left-parenthesis:

    ./netsynth solve code/examples/diamond.ltl | grep "^("
  4. Another important command is experiment, which builds a randomized problem instance from a given topology:
    ./netsynth exper experiments/models/zoo/Napnet.gml
    You can see the generated LTL specification by typing:
    ./netsynth exper experiments/models/zoo/Napnet.gml | grep FORM
    You can also generate the .ltl file and then solve it separately (dumped as model.ltl). Additionally, you can visualize the generated experiment via the dumped files model.pdf (port-level topology, and initial/final switch configurations with initial rules as solid lines and final rules dotted), and switches.pdf (switch-level network topology):
    ./netsynth exper experiments/models/zoo/Napnet.gml -dump
    ./netsynth solve model.ltl

Other Tool Usage Scenarios:

  1. Running main experiments in the paper:
    1. Use the ./run_experiments.py script. Arbitrarily-many names can be specified (separated by spaces). If no name is specified, all experiments are run in alphabetical order:
      ./run_experiments.py <experiment_name>
    2. Allowed experiment names:
      NamePaper DescriptionPaper Figure(s)
      result_reach_topozoo_nusmv_allIncremental vs.
      Monolithic
      (p. 10)
      Figure 6(a)
      result_reach_fattree_nusmvFigure 6(b)
      result_reach_smallworld_nusmvFigure 6(c)
      result_reach_topozoo_netplumber_allIncremental
      Performance
      *
      (p. 10)
      Figure 6(d)
      result_reach_fattree_netplumberFigure 6(e)
      result_reach_smallworld_netplumberFigure 6(f)
      result_reach_smallworld_netplumbermcIncremental
      Performance
      ,
      last sentence (p. 10)
      N/A
      result_way_topozoo_batch_bigIncremental vs.
      Monolithic
      *
      (p. 10)
      Figure 6(g)
      result_way_fattree_batchFigure 6(h)
      result_way_smallworld_batchFigure 6(i)
      result_way3_smallworld_incrScalability (p. 10)Figure 6(j);
      Table 1-3
      result_way_smallworld_incr
      result_reach_smallworld_incr
      result_way3_smallworld_incr_impInfeasible Updates,
      switch-impossible (p. 10)
      Figure 6(k);
      Table 4-6
      result_way_smallworld_incr_imp
      result_reach_smallworld_incr_imp
      result_way3_smallworld_incr_ruleInfeasible Updates,
      rule granularity (p. 10)
      Figure 6(l);
      Table 7-9
      result_way_smallworld_incr_rule
      result_reach_smallworld_incr_rule
      † Note #1: We originally ran the rule-granularity experiment with incorrect parameters, causing inflated numbers for rule-granularity wait removal in the paper (last 2 columns in Table 7-9 of Appendix D). The experiments now correctly report these as being much smaller (especially the last column).
      * Note #2: The text at the end of "Incremental vs. Monolithic" and at the beginning of "Incremental Performance" on page 10 refers to the incorrect figures. Incremental-vs.-Batch is Figure 6(g-i), and Incremental-vs.-NetPlumber is 6(d-f).

    3. Experimental data corresponding to the above experiments is included in the tarball at:
      netsynth/experiments/data/<experiment_name>.csv
      The CSV columns are defined as follows:
      ColumnDescription
      filenameexperiment filename
      suc_oneSolver #1 - success code: 1=success, 0=failure (timeout or out-of-memory), 2=impossible
      tim_grphgraph generation time (in seconds)
      time_oneSolver #1 - total runtime (in seconds)
      labl_oneSolver #1 - number of Kripke structure nodes re-labeled by model-checker
      call_oneSolver #1 - number of switch/rule changes during synthesis
      chk_timeSolver #1 - total model-checking time (in seconds)
      diffwhether generated update sequence is non-trivial, i.e. not simply lexicographic order (1=yes, 0=no)
      rulesnumber of flow-table rules (same as switches for switch-granularity)
      nt_rulesnumber of non-trivial (i.e. updating) flow-table rules (same as nontriv for switch-granularity)
      switchesnumber of switches
      nontrivnumber of non-trivial (i.e. updating) switches
      num_pairnumber of source/destination pairs (diamonds) in experiment
      suc_twoSolver #2 - success code: 1=success, 0=failure (timeout or out-of-memory), 2=impossible
      time_twoSolver #2 - total runtime (in seconds)
      labl_twoSolver #2 - number of Kripke structure nodes re-labeled by model-checker
      call_twoSolver #2 - number of switch/rule changes during synthesis
      chk_tm2Solver #2 - total model-checking time (in seconds)
      wayptsnumber of waypoints used in experiment
      seedrandom seed used in experiment
      speedupspeedup of Solver #1, i.e. (time_two / time_one)
      num_wtsnumber of waits in generated update sequence
      wrm_timewait-removal heuristic runtime

  2. Solving a pre-defined problem instance:
    ./netsynth solve code/examples/diamond.ltl -verbose
    To use the wait-removal heuristic:
    ./netsynth solve code/examples/diamond.ltl -waitrem
    To use rule-granularity (instead of switch-granularity):
    ./netsynth solve code/examples/diamond.ltl -rule
  3. Generating and solving experiments for a given topology:
    ./netsynth exper experiments/models/zoo/Napnet.gml
    You can use NetPlumber instead of our incremental model checker. Note that rule-granularity must be enabled, and the property must be "reachability":
    ./netsynth exp experiments/models/zoo/Karen.gml -prop reach -rule -netplumber
    To use NuSMV instead of our incremental model checker:
    ./netsynth exper experiments/models/zoo/Bellcanada.gml -nusmv
    You can alter parameters of the "diamonds" discussed in Section 6 of the paper. For example, the -pairs parameter specifies number of source/destination pairs (i.e. number of diamonds), -prop specifies LTL property type (either reach for reachability or way for waypointing), and -waypoints specifies number of waypoints. The -seed option specifies a random seed.
    ./netsynth exper experiments/models/zoo/TataNld.gml -pairs 2 -prop way -waypoints 3 -seed 19
    Most numeric options allow you to specify a fraction of the maximum value, and this is specified as a negated floating point between 0 and 1. For example, the following lines
    ./netsynth exper experiments/models/zoo/TataNld.gml -len -0.5 -waypoints -0.1
    ./netsynth exper experiments/models/zoo/TataNld.gml -len -0.5 -waypoints -0.9

    set the -len option to 0.5 times its maximum. Since this option controls the size of selected diamonds, this setting chooses diamonds that are half the size of the largest ones found in the topology. Similarly, the first and second commands set -waypoints to 10% and 90% of the total possible waypoints available on these diamonds.

    You can also generate a switch-impossible update. Note that the second example uses the Early Search Termination heuristic, speeding it up immensely:
    ./netsynth exper experiments/models/zoo/Napnet.gml -impossible
    ./netsynth exper experiments/models/zoo/TataNld.gml -impossible -cex -heuristic cex
    Switch-impossible updates can often be solved by using rule-granularity:
    ./netsynth exper experiments/models/zoo/TataNld.gml -impossible -rule
  4. Using Netsynth as an SDN controller:
    ./netsynth exp experiments/models/zoo/Napnet.gml -controller -mininet
    Upon pressing "Enter" to start the controller when prompted, if there is a failure due to "port 6633 in use", try first starting Mininet:
    sudo mn
    If that fails, try again and you should get a Mininet prompt. Just type "exit" and hit enter. The following Mininet command cleans up the virtualized network state, so try it if something strange is happening:
    sudo mn -c
    The experiments/data/mininet_fattree*.txt files describe in detail how to perform the experiments related to Figure 1 described in Section 2 of the paper. To summarize briefly, running the following command
    ./netsynth solve code/examples/fattree1.ltl -controller -pair a5:a5in1,a7:a7out1 -rule -mininet
    will solve the problem instance in fattree1.ltl using rule-granularity, and dump a Mininet script mininet_test.py. Once you press "Enter" to start the controller when prompted, you can open another terminal and type:
    chmod +x mininet_test.py
    sudo ./mininet_test.py
    This will initialize Mininet with the proper topology, and our running controller will be used to perform the update. At the Mininet prompt, you can type
    h1 ping h2 -i 0.1
    once our controller says to start the Ping Test, and you should see zero traffic loss throughout the update (type CTRL-C to terminate the ping command). You can add the -bad option to perform a wrong-order update
    ./netsynth solve code/examples/fattree1.ltl -controller -pair a5:a5in1,a7:a7out1 -rule -mininet -bad
    and you should see some traffic loss during a Ping Test. You can also use two-phase update instead of our ordering update, and see the rule overhead once the controller finishes:
    ./netsynth solve code/examples/fattree1.ltl -controller -pair a5:a5in1,a7:a7out1 -rule -mininet -twophase
  5. Running Netsynth as a JSON server:
    ./netsynth listen 8080
    See the file code/examples/diamond.json for the sequence of JSON commands which builds the same problem instance as code/examples/diamond.ltl. You can send this to a running Netsynth server by typing:
    nc localhost 8080 < code/examples/diamond.json