Implementing Pop-Routing - Final Evaluation

Hello again, for two months I have been working on my project and I have achieved all the goals.

An alpha version of my program was released for the mid-term evaluation.Since then I have fixed all the bugs, packaged the program for OpenWRT, tested the code and written the documentation.

Everything is available on the GitHub repository [0]

I structured my work opening by issues for all the bugs I had to fix and for everything I wanted to improve. Then, I organized the issues in milestones. Milestone 0.1 [1] is the one that I had to complete to finish the project. When that milestone was closed I made the branch “v0.1” [2].


In order to be sure that my program worked correctly. I wrote a simulator in python. It’s made by a small server, with the same interface as OONF’s telnet plugin, and two python libraries written by my mentor: cn_generator [3] and pop-routing[4]. The first one generates synthetic graphs using the Cerda-Alabern[5] algorithm, the second one is a pop-routing implementation in python. In the server I implemented the commands to push the NetJson[6] topology and the ones to receive the timers values.

When prince requests a topology from my test program, cn_generator generates a random graph and pushes it back; meanwhile using the python implementation of pop-routing, the references values are computed. The values received from prince are then compared to ones calculated using python.

The goal of tests is to verify that the difference between the reference and the measured values is always less than 1%.


I'm going to use my work to write my Bachelor Thesis, so I wanted to perform some measurements to check how well it worked.

My goal was to implement the algorithm on an embedded device, so I chose to measure the execution time on a “Ubiquiti Picostation M2HP” to see how well it was performing.

I branched Prince [7], modifying the code to measure the time needed to calculate the betweenness centrality and push it back along with the timers.

I used the graph generator to create graphs from 5 to 500 nodes, and I measured the time needed to compute with a sample every 10 nodes. For each sample I ran 5 tests, then calculating the mean and the standard deviation. The results are shown here:


As you can see from the graphic above, the computation time on the embedded device is quite good if we use the heuristic (8s for 100 nodes), it proved to be unusable without it (100s for 100 nodes)

OpenWRT Package

The last objective I gave myself in the previous post was to write a plugin for OLSRd. Since OLSRd isn't maintained anymore - and since all the developers are working on OONF - I decided to focus on it while avoiding the plugin. Instead, I wrote a makefile and packaged prince for openWRT / LEDE. The makefile hasn't been published yet in any openWRT feed, but it is hosted in my repository [8]. Instructions are available along with documentation.

Future Work

I’ll keep working on this project, mantaining the code and fixing the future issues. Since the graph-parser library is the last piece of code implemented in C++ and it depends on the Boost libraries, I’m looking forward to re-implement it in pure C.

One of my goals was also to run prince in my WCN (Ninux Firenze), but switching from OLSRd to OONF is taking more time than expected, so I'm hoping to try it in the future.











Powquty (PoWer Quality) - GSoC 2016

Dear Freifunkers,

Now that GSoC 2016 comes to its end, please allow me to update you on the powquty project. Despite some delays regarding the hardware, the goals set for GSoC 2016 have been reached. Here follows a picture that shows a compact demonstration for powquty.

Small Powquty Demonstration

The picture depicts the set-up for powquty, which consits of a LEDE based wireless router, connected to the PC over serial interface, where a Termial session of the router is running. The oscilloscope is attached via USB to the router. On the router's terminal session we see that powqutyd has been started, with the correspondent messages shown on stdout. These message show the calculated power parameters.


For installing powquty follow these steps:

  • add the following line to your feeds.conf in your source directory:

src-git powquty

  • update the your feeds, then install powqutyd from feed
  • Include powqutyd in your config (make menuconfig) by choosing powqutyd from: Utilities --> powqutyd
  • Save and exit menuconfig  
  • Compile and install powqutyd
  • scp the ipk file to your router and install it
  • opkg install powqutyd_0.1-1_<target>.ipk

Note this package depends on the following libraries/packages, that have to be installed before installing powqutyd:

  • libmosquitto
  • libconfig
  • kmod-usb-acm (kernel module)

When successfull the powqutyd package will create:

  • the binary powqutyd in /usr/sbin
  • the configuration file in /etc/powqutyd/powqutyd.cfg

Before running powqutyd you need to configure it.

  • Powqutyd needs to read the measurement samples from the USB oscilloscope. The USB oscilloscope has to be plugged to the router before running powqutyd. The USB oscilloscope implements the USB Communication Device Class (CDC) device specification. This means that the kernel module kmod-usb-acm will recognize the USB oscilliscope once plugged and will create a tty device probably under /dev/ttyACM0. Depending on your setup this could be different. Check your system logs after plugging the USB oscilloscope to find out the actual path of the tty-device on your setup and adjust the path in the config file of powqutyd (/etc/powqutyd/powqutyd.cfg) accordingly. Note: if the tty-device is not set right the powqutyd will not start!
  • Powqutyd will send the calculated power quality parameters using MQTT-protocol to an MQTT-broker. This means that powqutyd requires IP connectivity between your router and the MQTT-broker. Of course this is given if you set up an MQTT broker on your router itself, but this is not a requirement, as long as the router has an IP connectivity to an MQTT-broker. For testing purposes we used mosquitto on the router as MQTT-broker. Depending on your setup you need to adjust the mqtt_host config option in your /etc/powqutyd/powqutyd.cfg accordingly. The mqtt_host config option is a string that could contain either the IP-address of the Fully Qualified Domain Name (FQDN) of the MQTT-broker. Note: at the current state, the MQTT-client implemeted by powqutyd uses the port 1883 with no SSL support.
  • Furthermore the powqutyd's MQTT-client is an publish only client, thus it will not subscribe and has no will. Nonetheless the topic under which the powqutyd's MQTT-client publishes needs to be set. This can be done by adjusting the mqtt_topic config option in your /etc/powqutyd/powqutyd.cfg accordingly.
  • Powqutyd sends three types of messages to the MQTT-broker: i)msg_device_online, ii) msg_device_data, iii) msg_device_offline. These messages are explained below, yet all of them use a common setting which is a (universally) unique id for the devices that communicate with the same MQTT-Broker. This way the MQTT-broker can differenciate between the messages it receives. This device-unique-id is set by the config option dev_uuid
  • It is possible to print the results messages that powqutyd sends to the MQTT-Broker to stdout. This can be set by the option powqutyd_print. If set to 0 (zero) powqutyd will not print the result to stdout.
  • Running powqutyd: Once all the configuration above are done powqutyd can be started by typing: "powqutyd &" to your terminal.

Work achieved

For the powquty project, my mentor and I set up a dedicated Github page accessible under the following link:

There the list of my commits can be seen under:


The following picture depicts the folder structure of the work done during the porject.

├── etc
│ └── powqutyd
│ └── powqutyd.cfg
├── include
│ ├── calculation.h
│ ├── config.h
│ ├── emulator.h
│ ├── helper.h
│ ├── mqtt.h
│ └── retrieval.h
├── lib
│ ├── libpqlib.a
│ └── PQ_App.h
├── Makefile
├── src
│ ├── calculation.c
│ ├── config.c
│ ├── emulator.c
│ ├── helper.c
│ ├── main.c
│ ├── mqtt.c
│ └── retrieval.c
└── test
 ├── mqtt_test.c
 ├── usb_test.c
 └── vserial_test.c

During the project I had to reschedule the tasks planned repeatedly according to the progress and to the other circonstances. The order of the tasks changed significantly from the original plan, yet it was necessary to achieve the Goals of the project. Finally the tasks I did were in the following order:

  • First I had ported the library to a binary blob that can be used on the router.
  • Next I ve implemented the MQTT-functionality.
  • After that, I started working on the emulator, then I started working on the USB communication. For that I followed a trial and error approach, for which I used the folder called test to try out different things. Strictly speaking it is not needed at all for the software to compile and run, yet I kept it for future reference. For the USB comuication I implemented two solutions: One using libusb, and another one using virtual serial port (termios.h), since i wasn't sure how will the USB oscilloscope will behave on the router and if any driver on the router will provide me with a tty device. luckily the kmod-usb-acm did so, thus i continued the project with the virtual serial port solution.
  • Once the USB communication was working, the next step was to retrieve the sampled data from the oscilloscope. First trials yielded the first sine signal as shown in the next figure

  • The picture shows ten sine waves corresponding to 200 ms, with 10kHz sampling rate, formed by 2048 samples. Yet as it can be seen the calibration was missing and the values were between +2500 and -2500. That is because the values (as seen in the background of the figure) where signed short numbers, and uncalibrated. (I used octave for plotting).
  • Once I was able to get the calibration parameters from the USB oscilloscope, I thereafter applyed them to the samples and got the expected sine - Wave with the Voltage-values expected in EU (RMS = 230 Volts) as shown in the next picture

  • After successful retrieval of the sampling values, I continued designing the software for powquty. I decided to use a multi-threaded approach with a Thread for sending MQTT-messages, a second for retrieving measurment samples and a third for calculating the power quality parameters. I included a ring-buffer as an interface between the retrieval thread and the calculating-thread.
  • once all three component were integrated and working together I added the configuration (using libconfig) instead of hard-coded MQTT-Broker address, and hard-coded TTY-device ...etc.

Goals and future work

As described in the first blogpost, the goal of the powquty project within GSoC 2016 is to create a LEDE package which ensures the following three functionalities:

  • Retrieving sampled voltage data from the power quality measurement device via USB
  • Calculating statistical power quality parameters (such as: avg. voltage, harmonics, ect.) form the retrieved voltage samples
  • Provisioning of the calculated parameters for retrieval and graphical representation

At this point the powquty project has reached its first big Milestone where the basic functionalities set for the GSoC 2016, have been completely implemented.
Yet the end of one milestone is the begin of the next milestone.  This is why I conclude with some propositions for future work on powquty:

  • Design and implementation of error handling
  • Migration of the config to uci config
  • Design and implementation of another log option than stdout
  • Design and implementation of a Luci App for easy configuration and showing results

Nonetheless, please allow me to express my gratitude to my mentor, Dr. Thomas Hühn, for his outstanding support, and constant availability. Also great thanks are due to Freifunk, whose distinguished voluntary efforts - not only in regard to GSoC - made this possible in the first place. Last not least, great credits are due to Google for encouraging this innovative type of value creation.


DynaPoint Final

Hi everyone,

this is the final blog post about DynaPoint. Short recap: I created a daemon which regularily monitors the Internet connectivity and depending on that activates and deactivates the proper access points. That way the handling with APs would become easier as you already could tell the status by the AP's SSID. I also created a LuCI component for it to make the configuration more easy.

In the past weeks I was able to add some new features, fix bugs and complete the LuCI component. Especially the latter was really interesting and gave me some knowledge about how LuCI works.

In the last post I mentioned that it's better to verify Internet connectivity by using wget instead of just pinging an IP address.
Consequently I switched from Pingcheck to wget. I also added an option to use curl instead of wget. With curl you also get the option to choose the interface for the connection.
When you provide internet via VPN-interface you can explicitly check the connection of that interface now. The reason why I don't use curl as default is because of curl's rather large size. For some routers with only 4 MB of storage it might be too much.

I also added an "offline threshold", which will delay the switch to offline mode. So for example when you set the interval to 60 seconds and offline_threshold to 5, the switch to offline mode will be made after 5 cycles of checking (=300 seconds).

So how does an example configuration look like?

To use dynapoint just add dynapoint_rule 'internet' and dynapoint_rule '!internet' in the desired sections in /etc/config/wireless:

config wifi-iface
    option device 'radio0'
    option network 'lan2'
    option mode 'ap'
    option encryption 'none'
    option ssid 'freifunk'
    option dynapoint_rule 'internet'

config wifi-iface
    option device 'radio0'
    option network 'lan2'
    option mode 'ap'
    option encryption 'none'
    option ssid 'freifunk-maintenance'
    option dynapoint_rule '!internet'

The configuration of dynapoint takes place in /etc/config/dynapoint:

config rule 'internet'
    list hosts ''
    list hosts ''
    option interval '60'
    option timeout '5'
    option offline_threshold '3'
    option add_hostname_to_ssid '0'
    option use_curl '1'
    option curl_interface 'eth0'

All of that can also be configured via LuCI:

If you want to try out DynaPoint for yourself please visit for more information.

Future work

Currently there is only support for one AP per state. In the next weeks I want to add support for multiple APs per state.
Also I want to add support for more rules. At this time there is only support for one rule "internet". I want to make this more generic and provide support for custom rules.


I want to thank my mentor Thomas Hühn for his excellent mentoring and great ideas during this project. 
Also of course thanks to Freifunk for letting me realize this project and thanks to Google for organizing GSoC.

Monitoring and quality assurance of open wifi networks out of client view (final evaluation)

Hi together,

now the time has come to explain the full Google Summer of Code Project. In both blog posts before I explained the work packages and structure of the Project [0][1]. In the first post I declare the three main subjects. Here is a short overview to remind of the project structure:


Mainline project

and seminars.

The sub-projects are background work for community projects.

The mainline Google Summer of Code project is to develop a new firmware for routers, based on LEDE [2]. The third point are seminars for enlightment of technical aspects of the Freifunk Community.


First I would like to list up all sub-projects and their status.

The first of the sub-projects is the hoodselector. For a final explanation of this construct I would like to explain the following points to give you a good understanding of this concept. On the Nordwest Freifunk community we had one big problem. Due to the batman-adv management traffic, the network setup is not really scalable. This problem also exists on many other communities where they have thousands of mesh routers inside one single network. If there are too many routers inside of one layer 2 network the batman-adv management traffic will flood this network and make it useless.


Therefore in the Nordwest Freifunk Community we decided to develop the concept of hood-networking. This concept consists of two main components: The hoodfile [3] and the hoodselector[4]. The hoodfile is a json file containing all informations necessary for a definition of a geobased hood. One hood is defined by a geostationary fixed quadrants, VPN-peering- and wireless configurations. Inside a hoodfile are multiple hoods defined[5]. Following an example of a definition of a hood:



     "name": "rastede",

     "bssid": "02:00:0A:12:A0:00",

     "defaulthood": false,

     "servers": [


             "host": "",

             "port": "10000",

             "publickey": "ca1b5487ffc20a1f90e0ac14e835d84ab9e52612b5ca62e073d0a13dad98775e"



     "boxes": [














A hood has the following definition:


– name

The name describes the region depending on its geo coordinates. For example, if you create a hood over the city Oldenburg(Oldb) (Germany), a good name could be Oldenburg or ol as short. Every name has to be unique inside a hoodfile. Redundant names are not allowed!


– bssid

The bssid will be set for the adhoc wireless interface. This is the main part of splitting the layer 2 network. Inside the bssid there is the IPv4 sub-network encoded which is in use inside the hood. In the above json part the following IPv4 sub-network is encoded “” dec to bin => “0000’1010 0001’0010 1010’0000 0000’0000” bin to hex => 0x0A 0x12 0xA0 0x00 hex to mac => 02:00:0A:12:A0:00. Therefore the bssid should also be unique.


– defaulthood

The defaulthood boolean is only true on the default hood. The default hood doesn't have coordinates and is the inverted form of all other hoods with geo coordinates.


– servers

Contains an array of VPN connection informations. These informations are:

VPN server address (host)

VPN port

VPN crypto key

One VPN server should be used for one hood only! If two hoods have the same VPN server, batman-adv will loop them over VPN.


- boxes

This 3 dimensional array describes the geographical size of the hood. The surface is rectangular. You just need two points per box to reconstruct it. Here is an example:




                                          8.09 #____________

                                                   |                  |

                                                   |                  |

                                                   |                  |


                                                                      # 53.36,




Each hood can have any number of rectangles inside the boxes array.


To make your life a little easier you can use the hoodgen[6] and source[7] to write your json with the required informations. This is a simple web visualization tool to plan hoods and generate the right json format for the hoodfile. This tool has been written by Eike Baran. Big Thanks to him for this helpful tool!


Now to the hoodselector.

It is a software that creates decentralized, semi automated ISO OSI layer 2 network segmentation for batman-adv layer 2 routing networks. This program reads the geobased sub-networks called hoods from the above mentioned hoodfile. The decision of choosing the right hood is made on following points: first, the hoodselector checks, if the router has a VPN connection. If it has, the hoodselector then checks, if a static geoposition was set on the router. If not, it tries to get a position using wireless based localization with the so called geolocator. The geolocator [8][9][10] is a software which makes it possible to receive a position based on wireless networks “seen” around. These informations will be sent to the openwifi map project [11]. Knowing the position of the router the hoodselector can find the right hood, because each hood is defined with geocoordinates. If the Router doesn't have a VPN connection e.g. as a mesh only router, the hoodselector triggers a WIFI scan and searches for neighboured mesh routers in other hoods. If there is an other router with a different BSSID but with the same mesh SSID, the router chooses it’s hood based on the neighboured BSSID. I got much positive feedback from many other Freifunk Communities. Someone even created a integration request issue for gluon [12]. Gluon is a framework based on openWRT[13] and is very popular in the Freifunk community [14]. Before I will send this as a patch to gluon there remains one last urgent issue [15]. The current hoodselector is not able to handle mesh on LAN or WAN connections. So there is still a potential point of failure. Because persons who are not familiar enough with the hood-networking concept can accidentally interconnect hoods over the mesh on cable functions. I plan to fix this problem up to mid of september. When this issue is closed I would like sending patches for integration to gluon. Other issues can be found here[16].


On the Nordwest Freifunk community we currently have 10 active hoods including a default hood. That is a special hood where all routers will connect to, if they are not able to choose a hood, including also routers there out of ranges from other real hoods. After the last 3 months we can safely say that the setup works. Commits can be found here[17] All currently active hoods can be see here in this picture.




As next I would like to tell you about the second sub-project as a prework for the mainline project. In that part I work on a proper workaround with the continuous-integration (CI) system of Gitlab[18]. As I explained in the midterm evaluation, on our Nordwest community we started automatically building of nightly testing firmware images for our community firmware. The CI works now with a dynamical multiple core build processes and auto generated architecture targets out of source. At the moment it is not possible for Gitlab to handle high verbose inside the web-engine while the build process. I discussed the problem with the gitlab team and open an issue [19]. The CI builder is very helpful for the developing process of the monitoring drone. Here you can see the result for the local community image[20] and for the monitoring-drone [21].


Mainline Project.

The mainline project was to create a new firmware for monitoring and quality assurance of open wireless networks. So I started reading of informatins about openWRT [13] and LEDE [2]. I decided to use LEDE as base system. I know there still no release to use this as a defined base structure (we are all looking forward to this moment) but since july 2016 I am on the developer list and the way where LEDE is growing looks good. Next I looked for a build management script. First I thought about using make and Makefiles but this was not my favourite, so I decided to use the buildscript from the Franken Freifunk community as base, which is written in bash. Now I'll explain the structure how to work with and use it. The following directories and files are important for basic work:


buildscript ← File

     BSP ← Dir

     Community ← Dir

     build_patches ← Dir

     modules ← File


The buildscript is mainly a bash script for a humanly working with this buildroot. In other words it is an abstraction from the LEDE build ENV.


Inside the BSP directory are all necessary architecture specific informations.

BSP means Board-Support-Package. Also inside this directory are default informations like the shell banner system configs and so on.


The community directory includes community specific configurations, similar like the gluon siteconf [22]. Currently there are only two config parameters inside: first the "AP SSID" to set a default SSID with witch WIFI network should the monitoring-drone connect and the second parameter, the "AP BSSID" to set a node specific BSSID in case if more than one router with the same SSID is present. Then the monitoring drone is pinned on one specific node. This config parameter will be dropped in the future because it is not really effectively if a default BSSID is set . In future I plan to configure thous parameters over an extra web interface[23].


In the build_patches directory you can put patches for LEDE or if you what you can also put patches for each package repository. Here is a schemata:




         0001-this is a patch.patch

         0002-this is another one.patch


         0001-this is a patch.patch

         0002-this is another one.patch


The last file is called modules. Inside this file you can add external package repositories and also select specific packages out of this repositories. Following an example:





OPENWRT_PKGS="libwlocate lwtrace ffnw-node-info hoodselector"


Clemens and I discussed about the API design[24] regarding the communication between the monitoring drone and the netmon core. So we met together. Here a picture:

Jan-Tarek Butt (left) and Clemens John (right)


At last point were the seminars. During the Google Summer of Code we started to gave seminars for technical aspects of Freifunk because we have not enough developers and system administrators. That is mostly a big problem in volunteer activities. On the hacking sessions we follow a simple structure:


– two lectures about Freifunk technical aspects.

– discus about the contend of the lectures

– work session on projects


On the first hacking session at the 28. may 2:00 PM we created video recordings of the two lectures, you can find them here[25]. The next hacking session were failures because of Clemens and my exams. In future there will follow other streams about tecnical aspects of Freifunk.


Last but not least, my future plans:

For the hoodselector, I plan to close up the last urgent issue[15] that I mentored in the above for the migration into gluon I also started prework on gluon for this. One part was the implementation of a sequential code minifying process at compile time [26]. Also some other issues are still open so I will continuing the work on the hoodselector[16].


For the monitoring firmware they currently is just configurable over ssh. A web interface should follow soon and also a plugin system for community specific monitoring data requests.


On the Kieler Linux information days[27] inside the Kieler Innovations- and technology center I will hold amongst others 4 presantations about Freifunk relevants themes:


    Hoodselector - Network segmentation for Layer 2 routing at 11:00 (16.09.2016)[28]

    Wireless-based localization ( project) at 13:00 (16.09.2016)[29]

    OpenWRT Embedded Linux distribution at 16:00 (16.09.2016)[30]

    Freifunk Kiel/Nordwest (2016) - year review at 16:00 (17.09.2016)[31]








[6] http://hood.ffnw/hoodgen.html#


























SWOON: Simultaneous Wireless Organic Optimization within Nodewatcher - Final steps.

This blog post concludes the work I did during the Google Summer of Code 2016.

Spending the summer on nodewatcher was a pleasantly laborious exercise. Although my proposal concerned a development of a new algorithm, I realized that I also had to prepare various other components so that the algorithm would work. I started by sketching a short plan of different components I had to integrate for my algorithm to work. To remind the readers, SWOON is an algorithm for an efficient allocation of wireless frequencies in a densely populated area where many wireless access points interfere with each other. Before any work could begin, I had to install a local version of nodewatcher. I did not want to interfere with wlanslovenija's mature network and I needed a small network of my own to run these tests. To find such a network, I collaborated with a non-profit organization based in Berkeley, California. They provided me with access to a building outfitted with more than 10 wireless access points. The wireless access points in this testbed are extremely diverse. They come from various manufacturers and not all broadcast on the 5GHz band. This allowed me to work with issues unique to community networks: software has to be built ground-up to be extremely modular and it has to support a diverse range of equipment, since there is no central planning authority.

I started with writing the data collection module, on which I have reported in my previous blog posts. Once I was able to work with the data, I worked on a different algorithm which detected rogue nodes in networks. This is especially useful for network maintainers who now have information on which nodes are most harmful to their network. They can now significantly reduce interference by working together. Algorithms on this scale have to be extremely efficient: I derived a complexity bound of O(E * log(V)) where E is the number of edges and V is the number of vertices in a graph. This allows the algorithm to scale all the way to wlanslovenija's network or more, as it is almost linear. In order to achieve such scalability and efficiency, I had to peruse state-of-the-art graph theory research and utilize complex data structures (the one I used is called a disjoint-set data structure) to quickly order datasets in accordance with our needs.

I then moved on to the main algorithm, which took weeks to even rigorously define, let alone code up. I first considered implementing the Beigel-Eppstein coloring algorithm, which is known to run in ~O(1.3^n) time, but the complexity of the algorithm rendered it impractical. It relies on 19 different subcases which are iteratively used to simplify the constraint satisfaction (CSP) instance. Instead, I reverted to a custom implementation of a state-of-the-art greedy approach, which had to be modified from the source code of NetworkX, a leading open-source graph manipulation package. I devised a custom way of ordering the nodes in a graph to correctly prioritize wireless access points. The algorithm starts with looking at all the 'neighbors' (other nodes your radio detects) and computes the 'busyness' of each frequency band. We then minimize joint interference through the algorithm.

We observed an interesting property when running this algorithm on our wireless testbed. Most frequencies were moved to minimize interference, but some got worse. At first, we thought it was a bug, but we did eventually discover that some nodes must pick up more interference for others to remain noiseless. This perfectly coincides with our goal, which is to minimize the interference over all nodes, not every single node.

Next steps

One major problem with the algorithm is how unreliable 'signal' data is. We were thinking of coming up with a better metric to measure link quality instead of using signal strength. We were considering using the number of packet collisions instead. The modular design allows us to painlessly replace the metric without having to understand the entire algorithm.

We also noticed openWRT's iwinfo doesn't provide information about channel widths of access points. Adding this data would allow more accurate calculations instead of assuming all channels are 20MHz wide.

Finally, nodewatcher doesn't yet have support for issuing node-specific warnings. I'd love to use such a warning to let a maintainer know that their node needs to change the channel.

However, I am confident this algorithm will enhance our user's experience.

All my contributions can be seen on this link:

If you're interested in the timeline of the development, look at the following pull requests on nodewatcher's GitHub:
Bug fixes related to a local installation of nodewatcher:
Data collection module:
Command that users can use to export data from the data collection module:
Improving the data collection module:
Algorithm that detects rogue nodes in one's network:
Additional options for user-friendly data export command:
Testing framework for the rogue node algorithm + improvements:
Channel allocation algorithm implementation (not merged yet):
Updated data in nodewatcher/core:

GSoC: The ECE configuration system - summary

The Google Summer of Code is almost over, so in this blog post I'll give a overview over the targets I've met (and those I haven't).

Code repositories

All code in the first two repositories has been developed by me during the GSoC. The third link shows the work I've done to integrate a ECE backend into libuci.

What is working

As described in earlier posts, my GSoC project was a configuration storage system for OpenWrt/LEDE, trying to solve various issues of the UCI config system. The principal points of this new system are

    • ubus-based config daemon maintaining a central storage database file
    • JSON-based configuration data model
    • Validation based on simplified JSON-Schema

The Wiki at gives a good overview of the design and the usage of ECE and describes many features in detail. The pkg-ece package feed can be used to build and install the different components of ECE on OpenWrt/LEDE easily.

If you've worked with OpenWrt/LEDE, you probably know the UCI config system. A UCI config file looks like this:

config system
        option hostname 'lede'
        option timezone 'UTC'

This format is very simple: Each file (called "package") has a number of sections (named or unnamed) of different types (this example from the "system" package has a single unnamed section of type "system"). These section contain options with single values or lists of values.

Unnamed sections are usually accessed using indices, for example a command to set the hostname would look like this:

uci set system.@system[0].hostname='betterhostname'

With the simplicity of UCI, there come various issues and missing features; these are only a few of them:

      • The fixed data model (package/section/option) makes some kinds of configuration very awkward: In the example above, the index 0 must be given for the system section, but having a second section of this kind would not make sense. In other cases, deeper configuration trees must be flattened to be stored in UCI, making the configuration harder to understand
      • All values in UCI are strings, which often causes inconsistencies (booleans are usually stored as '0'/'1', but several other pairs like 'false'/'true' and 'off'/'on' are supported as well; different users of UCI sometimes parse numbers differently)
      • UCI doesn't have built-in validation. Frontends like LuCI usually validate the entered data, but as soon as the CLI client is used, no validation is done.
      • UCI always stored the whole configuration file and not only changes from the defaults, making the storage inefficient on overlay-based filesystem setups as they are common on OpenWrt/LEDE
      • In some situations, upgrades to default values should also affect the effective values; but only if the user didn't change the values themselves. With UCI, this is not possible, as it doesn't store the information if a value was changed by a user.
      • UCI allows comments in config files, but they are lost as soon as libuci or the CLI tool is used to modify it

The configuration given above could be represented in ECE as this JSON document:

  "system": {
    "hostname": "lede",
    "timezone": "UCI"

Note that this is only the external representation of the configuration; internally, it is stored in a more efficient binary format.

JSON gives us a lot of features for free: arbitrary configuration trees with proper data types. Existing standards and standard drafts like JSON Pointer and JSON Schema can be used to reference and validate configuration (the JSON Schema specification is simplified for ECE a bit though to allow more efficient validation on embedded systems).

The command for changing the hostname would look like this in ECE:

ece set /system/hostname '"betterhostname"'

The quoting is currently necessary to make the string a valid JSON document; this may change in a future version.

The whole configuration is saved in a single JSON document, but the specific format is not defined by a single schema; instead, each package can provide a schema, and the configuration tree is validated against a merged schema definition.

The schemas also provide default values for the configuration. Adding documentation for the configuration options to the schemas is planned as a future addition and might be used to support the user in configuration utilities and automatically generate web-based or other interfaces.

This gives only a small example for the usage of ECE, the abovementioned ECE Wiki contains much more information about the usage of ECE and the ideas behind it.

In addition to the daemon and a simple CLI utility, I've developed libraries for C, Lua and Shell which allow to access the configuration. While there are still some features missing (some points for future work are given in ), I think most of the missing pieces can be added in the near future.

The UCI/ECE bridge

When I proposed my project for the GSoC, I didn't aim at making it a full replacement for the current UCI system, at least not in the near future. While the possibility to move some of UCI config files into the ECE config database had been my plan from the beginning, my ideas for backwards compatibility didn't go further than a one-time import from UCI to ECE, and one-way generation of UCI config files from ECE.

After talking to a few LEDE developers and package maintainers, it became clear to me and my mentors that many people are interested in replacing UCI with a better system in the not-too-far future. But for ECE to become this replacement, a real two-way binding between UCI and ECE would be necessary to allow gradual migration, so configuration utilities like LuCI (and many other utilities somehow interacting with UCI) don't need to be adjusted in a flag-day change.

An incomplete design draft for this UCI/ECE bridge has been outlined in . The code found in the UCI ECE backend repository linked above implements a part of this bridge (it can load "static" and "named" bindings from ECE into UCI, and commit "static" bindings back to ECE) and has been implemented as an API- and ABI-compatible extension to libuci. The development of this bridge has taken a lot of time (much more time than I had originally scheduled for UCI compatibility features), as the data models of UCI and ECE are very different.

Future work

Of all points given in , finalizing the database format is the most important, as any future change in the storage format will either break compatibility or involve some kind of conversion. When it is clear the format won't be changed anymore, ECE should be added to the OpenWrt community package repository to make it easily accessible to all OpenWrt and LEDE users.

After that, other points given in the TODO should be dealt with, but none of those seem too pressing to prevent actually using ECE for some software (but some of the points given in the first section of the TODO page would need to be addressed to properly support software that requires more complex configuration).

Last, but no least, I'd like to express my gratitude to my mentors and all people in the OpenWrt, LEDE and Freifunk communities who have helped me develop ECE by giving guidance and lots of useful feedback, and to Google, who allowed me to focus on this project throughout this summer.

GSoC2016 Wrapping up: A crypto module for

The last weeks

So it's been a summer. Wow. It was an amazing experience taking part in this project, I feel like I have learned a lot and I hope that my work will be useful to others.

I want to take this opportunity to highlight what I set out to do and what I achieved in the end. The last weeks were probably the most satisfying bit of the entire project as modules that I had written weeks prior were slotting together seemlessly and things suddently just started to work. At the same time they were also the most frustrating with my code having two bugs that took me almost 2 weeks to finally track down.

Most of my work can be found in this repository, on the qaul_crypto branch.

I did some work on a different project, mildly related to which might become useful soon.
Most of what I have done is backend work but there is an example application you can run. The source code compiles and has been tested under Linux (Ubuntu 14.04 and Fedora 24). By running the qaul-dbg binary (under src/client/dbg/qaul-dbg you will create two users (to emulate a communication between two nodes), add their public keys to a keystore and then exchange and verify a signed message. Feel free to play around with the code for this demo, that can be found under src/qaullib/qcry_wrapper.c.

In this final blog post I will talk a bit about what I have done, what it means for the project and how my ~2.2k lines of c-code contribution will affect the future of

What I have done

The basic idea behind my project was to provide a cryptography submodule to to make it a safer and more verifiable place to communicate in. Part of that are of course ways to sign and verify messages but at the same time a core aspect of that are also user identities.

The two biggest parts of the crypto module are internally referenced as qcry_arbit and qcry_context. As I have already explained in previous blog posts, those are the Arbiter (which provides a static API to use in the rest of the library) and the Context which holds the actual "magic" of signatures, identities, keys and targets. In an earlier diagram there was a dispatcher. However due to testing the functions, it was deemed "overkill" and the functionality was integrated into the arbiter, meaning less abstraction layers and more flat code (which is always easier to understand and maintain).

With the arbiter in place it is now possible to create unique users with a unique fingerprint that can be shared on the network to identify people as well as sign and verify messages. What has also been done is provide new message types for OLSR (the routing protocoll used in to propagate this new information among nodes.

What I haven't yet done

Unfortunately there were some delays due to problems with the main crypto library in use in the project as well as a few bugs that really slowed down progress in the last few weeks. Due to that the entire encryption part has been delayed. There are functions planned and partially provided to take care of these tasks however no code behind them yet to implement it.

The feature is currently in planning and will land in a later patch, probably after the initial merge of the module has gone through as there are a lot of things to be taken care of.

Current state

Initial User signup dialogue

As said above, it is currently possible to create users, sign and verify messages and to flood the users fingerprint as well as public key to other users. However this doesn't address a few problems that we have had while integrating the arbiter API into the rest of libqaul. Due to technical limitations in the communication system it's currently not possible to sign private messages. This is due to how the communication subsystem works; which is currently being redesigned from scratch.

This means that any merge that will go through now will need to be adjusted to work with a new communication backend in a few weeks. As such, it is a bit unclear when exactly and how the crypto code will be merged. I am looking forward to working with the team on resolving these issues. And am also looking forward to a new shiny communication backend. But for now it means that merging the code I've written for the Summer of Code might be difficult.

New message types were added as well to provide a way to exchange these new payloads (signatures, public keys, fingerprints, etc) without breaking backwards compatibility with older nodes. What happens is that new nodes send out both a new and an old hello message. Other new nodes ignore the old hello message and can address the new node via it's fingerprint and use verifiable channels of communication while old nodes are oblivious to any change. Until they are updated :)

In conclusion

The Google Summer of Code brought a very big step closer to being a more safe and secure place to communicate on. The crypto submodule is tested and easy to use. What might happen is that parts of the code get merged (the crypto submodule itself) without merging any of the code that hooks into the communication stack.

There are still things to be optimisised, probably some hidden bugs to be fixed and there definately is some work needed to make private messaging actually private.

This might be the end of the Summer of Code and a "final evaluation" for this part of the project but I am by no means done. I was interested in open source software before, wrote my own projects, contributed small chunks of code to other people. But this is the first time I have been deeply involved in a large community project and the first time I learned to deal with integrating with other peoples code. And it is very largely due to the Summer of Code, Freifunk and my mentor.

I had a lot of fun working on this project and I am looking forward to more contributions. Even if it was frustrating and very stressfuly at times I'm glad to have participated. The experience tought me a lot about communication in teams, software development and funnily enough signature alignments :)


First of all I want to thank my mentor Mathias Jud to have introduced me to and the Google Summer of Code. I also want to thank him for his support and guidance with problems I had while interfacing the arbiter with the rest of libqaul.

In addition I want to thank saces, another member of the team who helped me in resolving dependency issues as well as problems I caused in the build system which prevented my code from building on Windows (woops).

Lastly want to thank Freifunk for providing me with this opportunity as well as Google for organising and sponsoring the Summer of Code projects.

Google Summer of Code 2016: External netifd Device Handlers - Final Milestone



The past weeks have felt very satisfying in terms of coding. With the main structure in place, all that I had to do was add features, test, iron out the wrinkles and prepare my code for submission to the maintainer. Adding features was fun because it felt like taking big steps forward every day with immediate feedback.
There were a few stubborn bugs, though. Despite taking the better part of a week to find, they were -- luckily -- easy to fix. They usually required little more than changing the order in which code executed which meant swapping a few lines of code.
Rebasing the netifd source code on to the current version went very fast and resulted in three separate commits; two small ones to prepare the existing code base for my additions and one pretty big one adding my ~2000 line .c-file.

As this is the blog post wrapping up my Google Summer of Code, I am going to summarize the entire project. This probably means that I will repeat some of the points I have already explained in my previous posts.


I set out to implement a way to open up OpenWRT/LEDE's network interface daemon (netifd) for new device classes.
Until now, netifd was only able to handle device classes for which a handler was hard-coded into the daemon. I added a way to generate the necessary device handler stub from JSON descriptions and interface them over ubus with another process that handles all device-related actions such as creation and configuration. Netifd is more open to experimentation and does not require maintenance from someone introducing a new device class.
Configuration of these devices still happens in the familiar /etc/config/network file.

Along with the ubus interface in netifd, I wrote ovsd, an external device handler for Open vSwitch. Together with ovsd, netifd can create and configure Open vSwitch bridges without any Open vSwitch-specific code added to it. It simply parses the configuration in /etc/config/network, sees that there is an interface on a device with type 'Open vSwitch', uses this name to look up the corresponding device handler from a list and calls the 'create' function that is part of the device handler interface.
The Open vSwitch device handler stub then relays the command along with the configuration blob to ovsd via ubus.

Ovsd processes the command asynchronously and answers using the ubus subscription mechanism. Netifd can then bring up the device as usual and attach protocol handlers and interfaces to it.

My work on netifd is not likely to get included upstream before GSoC ends which is why I have created a patch with my changes and put it in a repository here. The repo includes the LEDE source code as a git submodule and is easy to build.
The ovsd source code is hosted at GitHub along with instructions on how to install it.


This example file demonstrates all the available configuration options for Open vSwitch devices in a possible scenario featuring an Open vSwitch bridge with interface eth0 and a fake bridge on top of it:

# /etc/config/network
config interface 'lan'
    option ifname 'eth0'
    option type 'Open vSwitch'
    option proto 'static'
    option ipaddr ''
    option gateway ''
    option netmask ''
    option ip6assign '60'

    option ofcontrollers 'tcp:'
    option controller_fail_mode 'standalone'
    option ssl_cert '/root/cert.pem'
    option ssl_private_key '/root/key.pem'
    option ssl_ca_cert '/root/cacert_bootstrap.pem'
    option ssl_bootstrap 'true'

config interface 'guest'
    option type 'Open vSwitch'
    option proto 'static'
    option ipaddr ''
    option netmask ''

    option parent 'ovs-lan'
    option vlan '2'
    option empty 'true'

The lines set apart are Open vSwitch-specific options. They configure OpenFlow settings, control channel encryption and the nature of the device itself, which can either be a 'real' or a 'fake' bridge on a parent bridge and VLAN tagging enabled.

This is the JSON description from which the device handler stub is generated:

# /lib/netifd/ubusdev-config/ovsd.json
    "name" : "Open vSwitch",
    "ubus_name" : "ovs",
    "bridge" : "1",
    "br-prefix" : "ovs",
    "config" : [
        ["name", 3],
        ["ifname", 1],
        ["empty", 7],
        ["parent", 3],
        ["vlan", 5],
        ["ofcontrollers", 1],
        ["controller_fail_mode", 3],
        ["ssl_private_key", 3],
        ["ssl_cert", 3],
        ["ssl_ca_cert", 3],
        ["ssl_bootstrap", 7]
    "info" : [
        ["ofcontrollers", 1],
        ["fail_mode", 3],
        ["ports", 1],
        ["parent", 3],
        ["vlan", 5],
        ["ssl", 2]

The first four fields tell netifd the type of the devices and the name of the external handler to connect to via ubus. "bridge" and "br-prefix" signal the bridge capabilities of the devices and give a short prefix to prepend to devices of type Open vSwitch creating devices named "ovs-lan" and "ovs-guest" for the interfaces "lan" and "guest", respectively.
The "config" and "info" field detail the configuration parameters and their data types for device creation and for responses to the 'dump_info' method of the external device handler (see my earlier blog post).
I have created a manual on how to write a JSON description of an external device handler that goes into greater detail. You can find it here.


Because of the nature of the device handler I implemented, I could only test scenarios that arise from using Open vSwitch. These are bridge-like devices by design and not every device class someone might want to integrate with netifd will behave like them. I had to anticipate much of the behavior for non-bridge-like devices trying to make the ubus interface device class agnostic.

Also, while I tested ovsd with all the complex setups I could think of using fake bridges and wireless interfaces, there are probably edge cases where my implementation is insufficient. Ovsd may have to become stateful at some time.

At the moment, the JSON files from which the device handler stubs are created are a bit "human-unfriendly". Parsing the JSON objects fails unless they are written on a single line with proper EOF termination. Allowing pretty-printed JSON would greatly increase readability. What's more, the parameters' data types are cryptic enumeration values from libubox. Another translation layer turning numbers into readable types like "string" would also help users read and write description files.


In the future, I would like to add a way for external device handlers to send detailed feedback about requests they receive back to netifd within the context of the request. This way authors of external device handlers could provide device-specific information such as specific error messages when a command fails.
All the building blocks for such a mechanism are there:
  - ubus replies that are logically connected to an ongoing request and
  - the possibility to tell netifd what messages to expect via an entry in the JSON description file.

This way, messages and their formats could be defined by the authors of external device handlers on a per-device-class -- and even a per-command -- base. Netifd would then be able to handle these messages and write them to the logs along with information about the context of the ongoing transaction.


All in all, GSoC was a blast. Although challenging and frustrating at times, I am happy to have done it. This was the first time I had to read other people's code to this extent and at this level of -- for lack of a better word -- sophistication. It took me the better part of a year to really get a grip on the code base when I was working with it as part of the student project at TU Berlin but once I had a feeling for its structure, playing around with the features I added was fun. It feels rewarding to have worked on and contributed to "real world" free software.
From the organizational, side I am very happy with both Freifunk's and Google's way of managing the process. I always knew what was expected of me and was provided the necessary information in advance.


Now that my first GSoC is over, some thanks are due. First and foremost, I would like to thank my mentor and advisor Julius Schulz-Zander for introducing me to GSoC and for his counsel throughout the summer. Thanks to Felix Fietkau, original author of netifd and its maintainer, of whom I've learned a lot both indirectly by working with his code and directly when receiving feedback on my work. Finally, I want to thank Freifunk for letting me do this project and -- of course -- Google for organizing GSoC.

Syndicate content