GSoC 2017 – Add MPTCP support in LEDE/OpenWRT trunk – July progress

What we have so far

After lots of experiments, I figured out the way which enables the transparent MPTCP operation for both the client and the server (with the regular kernel).
I tested the configurations at my virtualized environment, check the video below. For configuration infos, please read the video description. (the post continues)

Continue reading “GSoC 2017 – Add MPTCP support in LEDE/OpenWRT trunk – July progress”

GSoC 2017 – Milestone 2

Following the rather stark change of direction after the last milestone (see my last post), I have worked on the integration of my project with Johannes Wegener’s: OpenWifi.

July Progress

For my software-defined networking (SDN) agent, I have added support for configuration through a UCI config file as well as process management through procd. This ties the daemon in neatly with the LEDE/OpenWRT system. Now, parameters such as the SDN controller’s address are read from this file and the configuration can be reloaded at runtime without stopping the agent.
Using the UCI system also exposes the configuration parameters to Johannes’ OpenWifi system. He and I discussed the bootstrapping process with our mentor and we have come up with the following idea: When a newly installed LEDE/OpenWRT access point first boots, it discovers the OpenWifi server via mDNS and fetches its configuration from it. With the address contained in the configuration, my SDN agent on the access point is able to connect to the SDN controller and thus integrate automatically with an existing centrally managed deployment. In the event of a configuration parameter change (e.g. a switch to a different SDN controller), OpenWifi can trigger a configuration reload to quickly update all access points in the network.

On the controller side, I have implemented a REST client to interface with OpenWifi. Through it, the controller can register with the OpenWifi server. During the registration, it installs its address and OpenFlow listening port in the UCI configuration which later gets sent to access points.
I have also begun writing a REST interface for my controller to offer more comfortable management of SDN applications and the network state. Right now, I can query the controller about its resources: access points, switches and clients. With the basics in place, expanding the interface to expose more SDN functionality should be pretty straightforward.

Next Steps

During the final part of this year’s GSoC, I want to focus on adding functionality, testing and documentation. I will spend the remaining weeks of the project like this:
1) write an SDN application
2) expose the app’s functionality via the controller’s command-line and REST interfaces
3) test it on the university department’s testbed
4) document its usage
5) goto 1)

Since the foundation for the SDN applications is in place and running, I am optimistic about getting a lot done during August. I will start with a client hearing map that keeps track of associated and unassociated clients in the vicinity of the deployment’s access points. Leveraging the hearing map, I want to implement a client load balancer that distributes associated clients evenly across available access points. I will also look into automated channel selection to avoid interference between neighbouring access points.
Finally, I would like to wrap up the controller in a docker image for easy deployment.

PowQuty Live Log Second Update

It’s been nearly a month since my last update on the PowQuty Live Log project and i would like to tell you, what has been done
so far and provide information on what will be done in the next month.

PowQuty got updated, to support Slack and mqtt event notification and can already be used in the current PowQuty version.
In addition to this, there have been some bug fixes during the last month and some new features were added.
On event occurrence the event gets stored in a csv file and each entry is displayed in the luci-app. To increase the usability,
a traffic light system will be added, which will show for each event type its occurrence time and show if the current values
are in violation of EN50160.

  • Green: Everything is ok, no violation
  • Yellow: Close to a violation
  • Red: This event time is in violation of the norm
  • The event messages contain a times stamp, the duration of the event and updated event Type information, as well as event type related
    information and GPS data.
    .

    As receiving notifications or emails on every event occasion can get noisy, we decided to provide a weekly summary of the events in
    addition to the regular notifications.
    The user will be able to decide if he wants to receive this summary, every event, or both. We consider using the traffic light system
    here as well, to increase the readability and enable users to understand the quality of their power supply network, without a lot of
    knowledge of the EN50160 norm.
    We discussed individual intervals and keep it in mind as a possible later feature.

    Best regards
    Stefan

    GSoC 2017 – wlan slovenija – Report 1 – HMAC signing of Nodewatcher data

    What’s been done

    The first blog post that describes the idea and goals can be read here.

    After getting a bit more familiar with the code base the first thing that had to be done was to set up the work environment. I chose to go the virtual machine route so an actual router did not need to be used, making the development easier. An instance of the nodewatcher is running on a virtual machine running Ubuntu Linux. It runs in a Docker development environment and is set up by using the provided Docker Compose configuration. To enable data collection from nodes the monitor system also needs to be running.

    To test the the nodewatcher’s HMAC signing capabilities I set up a dummy test node, turned on HMAC signing and used a python script to push some data on to the nodewatcher.

    The next step was to set up a development node. With a lot of help from my mentor Kostko I used firmware-core to create a LEDE virtual machine, compile nodewatcher-agent packages, transferred them to the LEDE machine, used SSH to connect to it, installed them and tested the basic nodewatcher-agent functions. The whole setup and development process was documented in detail in the nodewatcher-agent README. Then I set up the agent’s http.push module and pushed some data on to the nodewatcher instance.

    A local network like one in the above image was set up for development. Due to my lack of experience with networking I encountered some issues like not being able to ssh into the LEDE VM and not being able to send packets from LEDE VM to Nodewatcher VM, but with patience from my mentor it all works and the lesson was surely learned.

    What’s next

    So the hardest part is done, right? I am now working on adding a HMAC signing like it’s already done in the python script. It needs to be developed for both pushing the data from a node to the nodewatcher and pulling the data from a node.

    I am contributing using my github account.

    Onwards! Good luck!

    GSoC 2017 – Milestone 1

    June Progress

    During the past weeks, I have mainly worked on LoxiGen. LoxiGen is a compiler which generates OpenFlow serialization and de-serialization libraries for C and Java. I have used the tool before and was able to build on my own work introducing the necessary message types for my GSoC project. Since I have chosen ONOS as my Software-Defined Networking (SDN) controller, I used ONOS’ fork of LoxiGen as a starting point. This required hard-coding some message types to make ONOS’ fork produce valid C libraries. I am planning to get in touch with LoxiGen’s maintainers soon to try and figure out if some of my work can be used towards a merge of the two diverted code bases.

    [Edit: Major change of plan]

    In an older version of this blog post, I wrote that I was going to implement a kernel module to enable the de-coupling of hostapd and the physical access point. Yesterday, I had a long discussion with my mentor and Johannes, another GSoC participant for Freifunk (read about his project here). We decided to drastically change the direction of my project. Instead of aiming for the (undoubtedly) cool and advanced feature of running hostapd as a Virtual Network Function, I am going to focus my efforts on a simpler use-case. The reasoning is to have a more stable and ready-to-use toolset for the management of larger OpenWRT/LEDE deployments in the end. In other words: Do less but do it well.

    To this end, Johannes and I are going to work on a set of interfaces to make our projects compatible. The vision is as follows: I am going to write an SDN application that registers the ONOS controller with Johannes’ OpenWifi server. Whenever a new access point joins the network, it discovers the OpenWifi server and fetches its configuration from it. Included in this configuration are the address and port of the ONOS controller. Thus, the new network node is able to connect to the SDN controller without the need for manual configuration by the network operator.

    Next Steps

    As mentioned above, Johannes and I will have to establish interfaces for our projects to interact. We also need to set up a combined testbed to test our implementations. On my end, I will start by adding the possibility to configure the OpenWRT/LEDE agent that connects to the ONOS controller through UCI. That way, the agent’s configuration can be queried and altered through the OpenWifi REST API. This should be rather simple. Next, I will write a proper REST API for my controller as well as the application that communicates with the OpenWifi server. Then, I will add features for network management such as the ability to move clients to a specific access point or to ban them from connecting altogether. Lastly, I will write SDN applications for automatic network management, for example, a load balancer that distributes clients evenly across available access points that is powered by the data stored in a client hearing map.

    GSoC 2017 – Add MPTCP support in LEDE/OpenWRT trunk – June progress

    Info form the project

    For more info whats the goal of the project, please visit my first blogpost which is here.

    What done yet

     

     

     

     

     

     

    I created this simple topology for trying out the technologies. I’m still in experimenting status but have some results as well. This virtualized test enviroment run on my machine. The paths between the MPTCP supported machines are shaped to 10 Mbps. With iperf3 and Wireshark I verified that the MPTCP protocol is working fine: clearly shows 20 Mbps between the two MPTCP supported machine (I use the latest 0.92 MPTCP kernel which is based on the 4.4 kernel version). Tha path between the MPTCP and Endhost machines are not shaped, so the throughput is much higher than 20 Mbps. I configured shadowsocks-libev on MPTCP1 (ss-server) and Endhost1 (ss-redir) machine. Then I tired an iperf3 download between Endhost1 and MPTCP2. This looks like:
    Endhost1 <——————]TCP[——————-> MPTCP1 <———————]MPTCP[——————–> MPTCP2
    I successfully get the 20 Mbps on Enhost1 which is the aggregated throughput of path1 and path2. (continue)

    Continue reading “GSoC 2017 – Add MPTCP support in LEDE/OpenWRT trunk – June progress”

    PowQuty Live Log First Update

    As mentioned in my previous blog post, i am going to add a live log and notification system for
    certain events to the power monitoring tool PowQuty. The first steps have been done and the
    configuration has been extended.
    Three types of notifications have been added to the configuration options during the first month of coding.
    Namely email, slack and mqtt. Mqtt was in use before, but was extended to allow a second host and topic for
    the power quality events.
    The powquty configuration page was redesigned to use a separate tab for each notification option
    to increase overview.

    The old configuration page would have been very crowded with all the new options
    The new configuration view with mqtt tab open

    Power quality events, that cause a notification are:

    • Voltage dip between 10% and 90% of the reference voltage of 230V
    • Voltage swell above 110% of the reference voltage of 230V
    • Voltage dip < 10% of the reference voltage
    • More than 5% of the samples of one harmonic are above the threshold

    As the power supply network in Berlin was not willing to provide such events an option for test measurement
    input was needed. A file read flag for powqutyd was added and needs a little bit of clean up
    before a pull request on the upstream powqutyd.
    The library for the USB-oscilloscope provides the number of EN50160 events per measure cycle and
    the kind of each event. As of now some basic slack notifications are added, which provide the event
    type and the event start time from measurement start in milliseconds to the channel and team set
    in the luci web interface or under /etc/conf/powquty.

    Slack notifications with start time in milliseconds relative to measurement start, probably will be UTC or local in the future

    In the notification the type of event is provided to allow the network administrator to react directly
    to the changes, without to check the log any further.
    The other notification options will be added and tested soon.

    GSoC 2017 – Add MPTCP support in LEDE/OpenWRT trunk

    Brief intro

    My name is Ferenc Fejes. I’m MSc CE student at the University of Debrecen, infocommunication networks specialization. I glad to introduce my project which is Add MPTCP support in LEDE/OpenWRT. The main idea is from my mentor, Benjamin Henrion. If we have a Wi-Fi mesh network, there are probably more than one network path between the nodes. The point is, we can gain additional throughput if we use those path simultaneously.

    The goal

    Currently no MPTCP support in GNU/Linux nor Windows systems. So the key is, the user using regular TCP/UDP at his system until the first hop, which is a LEDE box with MPTCP support. At this point, this router operating as an intercepting proxy: read the incoming traffic from the host, and distribute that on multiple interface, using MPTCP. At receiver side, we can do the same but in reverse order: get the data from the MPTCP connection and send is to the sink host in regular TCP (or UDP). With this operation, the whole MPTCP transmission remains hidden for the end hosts, but they will enjoy the gain from it – because MPTCP has a good capability to aggregate the bandwitdh of the different paths. Of course, if the bottleneck between the end host and the first hop, the user did not get any gain from this operation.

    The plan

    The key steps for reach the goal of the project:
    1. Set up virtual/real machines with MPTCP support. This is not a problem since kernel patches for MPTCP support available.
    2. Make a simple multipath topology: end hosts with no MPTCP support, two machine with MPTCP support, functioning as a router and has two different network path between them
    3. Search and configure an efficient and transparent proxy software on them, which can suitable for intercept TCP traffic and work as a tunnel for other protocols (like UDP, SCTP, etc.)
    4. Reproduce the working configuration on LEDE supported devices, with two Wi-Fi bridge links between the LEDE boxes.
    5. Verify the aggregation with iperf3 measurements.

    GSoC 2017 Project – OpenWifi: LEDE/OpenWRT configuration Mangement

    GSoC 2017 – OpenWifi

    Hi, my name is Johannes Wegener and I’ll be working on OpenWifi this Google Summer of Code. I’m 27 years old and study computer engineering at TU Berlin. In this blog post I’m going to explain to you what OpenWifi is and what should be done during this summer of code.

    What is OpenWifi?

    OpenWifi is a OpenWRT/LEDE configuration management system. It is intended to manage a bigger or smaller amount of OpenWRT/LEDE devices.

    If a new access point joins a network it is be able to auto detect the management Server and register to it. After the node has been registered its configuration (static configuration like what you’ll typically find in /etc/config/ on OpenWRT/LEDE devices) will be downloaded by the server and stored in a database.

    It is now possible to query and modify aspects of the configuration. It also possible to change values depending on other values. This means configuration changes can be applied to a lot of different routers. There is an older templating system which shall be replaced by a new graph-oriented one. It also manages SSH-Keys, has a rudimentary file upload functionality (for uploading new images for example) and extensible API. It is possible for example for a node to ask for an image it should install. (Currently this is not very dynamic – but it is intended that an image could be selected on various parameters)

    The Server also regularly pulls the health-state of the node and displays it in an overview. Furthermore the server acts as a luci2 proxy.

    It is also extensible via PlugIns and is able to serve as an entry point to other services like icinga or location services. (Both already have a proof of concept PlugIn available)

    How does it work? aka what makes it tick?

    The main software is written in python and uses the pyramid framework and sqlalchemy as ORM. It uses pyramid-rpc for json-rpc requests (which is used for nodes to register for example) and cornice for a REST-style API (which is intended for the user of the system). The Core-System can be found in this repository.

    Most of the tasks operating on nodes are done by a jobserver that uses celery – so that they don’t block the main thread.

    All Webviews have been moved to a different repository and are realised in fact as a PlugIn. (If you just want to manage your nodes on CLI/with scripts this will be possible in the near future!)

    The nodes use a notification script written as a shell script. It uses a fixed DNS entry (openwifi), a configuration file (/etc/config/openwifi) or mdns (using umdns or avahi) to detect a server and register to it. The packages can be found in the openwifi-feed repository. There is also a boot-flasher which is intended for flashing an alix2-style board from ramfs – since it is also possible to execute commands on the node I’ll integrate an update solution that uses sysupgrade.

    The communication between the server and the node is realized currently via rpcd. But one goal during this Google Summer of Code is to abstract that and realize it via a rpcd-communication-PlugIn – this would make it possible to also a NetJSON-communication-PlugIn for example.

    The PlugIns are realized with python entry points. There are some special named entry points which will extend the main application. You could have a look at the example plugin to get an idea how it works.

    How to try it?

    You can easily try the software with docker. Navigate to the Docker directory – there three files that will assist you with the setup. In conf.sh you setup if you want to use LDAP for authentication, avahi for mdns announcement and dnsmasq as dhcp server in the docker container.

    With build_image.sh you build the docker image. It tries to detect if you need to use sudo for docker or not. Last but not least you need run_image.sh to start the image.

    You can easily add PlugIns to the docker image if you just check them out or copy them inside the Plugins directory. To start off I would recommend to add the Web-Views Plugin and use avahi. Now you can navigate your browser to http://localhost:6543 to see the webviews (you need to restart the container after Plugin install – use docker stop OpenWifi and docker start OpenWifi).

    What is needs to be done?

    In the next section I’ll explain what should be done during Google Summer of Code. I need to prioritize these things because I’m not sure if it is possible to do everything. I think most important things are Testing, Authentication and the new graph-based database model.

    Testing-Infrastructure

    Currently just very few things have tests. But because it is possible to start a LEDE container in docker (there are some scripts helping to create a LEDE container in the Docker/LEDEImage directory) a lot of things are possible to test with docker orchestration. I want to provide a small LEDE image with the code to test it.

    Before adding big new things I like to transfer the development to true test-driven development and having test for at least 90% of the core component code. And after that continuing development by writing tests first.

    For that I would also have a look at coverage.py.

    Security and authentication

    There is a simplistic authorization for OpenWifi with a LDAP backend. I would like to add authorization based on user/password (without LDAP), API-Key and client side certificate (for the nodes to authenticate theirself against the API).

    I would like to have the authorization as granular as possible. Authorization should check whether the authorized identity is able to operate on this node and what kind of action is allowed.

    Security is provided by TLS. Last week I added the last bits to also use https for client communication – but right now it needs to be setup up by the user. I would like to add the appropriate hooks to the notification shell script.

    Expand new graph-based DB-Model

    The new DB-Configuration model is based on a graph – where configurations can be connected by links (the link can contain addition information – like what kind of link it is – currently the addition data is the option name (for example if you have a wifi-iface configuration the “device” links it to a wifi-device)).

    The model is implemented and there is a query API to get and set options. But for communication purposes the configuration is stored as uci-json-config. There is code to convert between these two (but the one from uci to graph-model needs quite some more intelligence to detect everything right). There are also some hooks that update each part. But the update process is not consistent – the graph-based config gets a new ID for example. It would be nice to have a consistent conversion.

    Furthermore I like nodes to share parts of a configuration. This should be easy to implement with some small DB changes. For this consistency is also very important. By default UCI generates unique strings for every configuration – this could be used for consistency.

    The DB-Model also currently lacks creating new configurations and reordering configurations.

    API

    The API to modify nodes should get expanded and everything should get documented. (see above) This should be done in code and a document generated by sphinx.

    I also like to implement a CLI program to use the API.

    Versioning

    The uci-json parser supports diffs between configurations. I would like to save a diff for each change which is applied – to have roll back configurations or delete a specific change.

    There is a simplistic revisioning implemented. But the diff should be updated to a class of its own with json import and export and operations to apply a diff to a UCI configuration. (upgrade and downgrade)

    Modularity and expandability

    OpenWifi is right now is already quite modular – but I also want to modularize configuration parsing and communication. It would also be nice to have some interoperability with OpenWISP.

    I use alembic for tracking database changes it would be nice to find a good way to use alembic for database changes needed by PlugIns as well.

    Scheduled Updates

    I want to schedule config updates – for example if you have a mesh you probably want to update the deepest nested nodes first and than the ones above etc. – this should be easy with celery (as long as the mesh is known and somehow represented in the database).

    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 ‘http://www.example.com’
        list hosts ‘http://www.google.com’
        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 https://github.com/thuehn/dynapoint 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.

    Acknowledgements

    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.