Developing lightweight computation at the DSG edge

Commit 8ee2b304 authored by Roger Pueyo Centelles's avatar Roger Pueyo Centelles
Browse files

Pending changes?


Signed-off-by: Roger Pueyo Centelles's avatarRoger Pueyo Centelles <rpueyo@ac.upc.edu>
parent 0a052624
# uc-monitor-go-test [![Go Report Card](https://goreportcard.com/badge/lightkone.guifi.net/lightkone/uc-monitor-go-test)](https://goreportcard.com/report/lightkone.guifi.net/lightkone/uc-monitor-go-test)
An initial implementation, in the form of microservices, of a distributed, decentralised and resilient monitoring system for the Guifi.net network nodes. It uses [AntidoteDB](https://syncfree.github.io/antidote/) and is part of the [LightKone](https://www.lightkone.eu/) project.
## Description
The monitoring application is distributed in three main blocks:
- Network description fetching and feeding: functional
- Automated nodes assignment among the different monitoring servers: functional
- Actual nodes monitorisation
- Uptime: functional
- SNMP: WiP
This implementation uses [Mathias Weber (@mweberUKL)](https://github.com/mweberUKL)'s Go client for AntidoteDB.
This document briefly explains the applications, how to run them and how the data are structured.
It takes advantage of the [AntidoteDB Java tutorial](https://github.com/SyncFree/antidote-java-tutorial) by [Deepthi Akkoorath (@deepthidevaki)](https://github.com/deepthidevaki) and [João Neto (@joaomlneto)](https://github.com/joaomlneto)'s [HTTP/HTTPS REST API for AntidoteDB](https://github.com/LightKone/antidote-rest-server).
## Installation
### Docker
Install `docker-ce` using your preferred method as [described here](https://docs.docker.com/install/).
### Go and required libraries
Install Go using your operating system's package manager or follow the [instructions here](https://golang.org/doc/install).
After installing Go, download and install the folowing external libraries needed:
- golang/glog:
`go get github.com/golang/glog`
- sparrc/go-ping:
`go get github.com/sparrc/go-ping`
- antidote-go-client:
`go get github.com/AntidoteDB/antidote-go-client`
### AntidoteDB Java tutorial
Get the tutorial's source code [here](https://github.com/SyncFree/antidote-java-tutorial) to download the code and [start the two AntidoteDB nodes](https://github.com/SyncFree/antidote-java-tutorial#starting-antidote-nodes).
### HTTP/HTTPS REST API
The AntidoteDB REST API server is no longer used by the monitoring applications, but it comes handy to perform quick tests like the ones in this document. You can follow the [instructions here](https://github.com/LightKone/antidote-rest-server) to install it..
## Running the application
### Fetch the network description and feed it to AntidoteDB
The Guifi-UPC network (a small fraction of the whole Guifi.net) description file is included in `assets/cnml/upc.xml` and is used by default. The `monitor-fetch` program fetches the data from the file and pushes it to AntidoteDB:
```bash
$ cd src/monitor/fetch/
$ go run monitor-fetch.go
19 nodes read from ../assets/cnml/upc.xml
63 devices read from ../assets/cnml/upc.xml
54 devices exported to /tmp/gmonitor2/devs.json
16 devices removed from AntidoteDB (0 success, 0 fail)
16 graphservers removed from AntidoteDB (0 success, 0 fail)
27 IPv4 addresses removed from AntidoteDB (0 success, 0 fail)
54 devices added to AntidoteDB (54 success, 0 fail)
54 graphservers added or updated to AntidoteDB (54 success, 0 fail)
67 IPv4 addresses added or updated to AntidoteDB (67 success, 0 fail)
```
Other small sub-networks' descriptions are available in the `assets/cnml` folder, some of them overlapping and some not.
Beyond the development and testing phase, the whole Guifi.net CNML description can be loaded (warning, it's HUGE, and it's GROWING):
```bash
$ go run monitor-fetch.go -cnml_file ../assets/cnml/guifi.xml
57642 nodes read from ../assets/cnml/guifi.xml
53461 devices read from ../assets/cnml/guifi.xml
39988 devices exported to /tmp/gmonitor2/devs.json
0 devices removed from AntidoteDB (0 success, 0 fail)
0 graphservers removed from AntidoteDB (0 success, 0 fail)
0 IPv4 addresses removed from AntidoteDB (0 success, 0 fail)
39988 devices added to AntidoteDB (39988 success, 0 fail)
39988 graphservers added or updated to AntidoteDB (39988 success, 0 fail)
49671 IPv4 addresses added or updated to AntidoteDB (49671 success, 0 fail)
```
### Assign network nodes to monitoring servers
Each monitoring instance consists of three pieces of code, `monitor-assign`, `monitor-ping` and `monitor-snmp`. Eventually they will be merged into a single one encompassing all the functions.
The `monitor-assign` program gets the whole Guifi.net network description from AntidoteDB, checks which devices are not being monitored (or are not being monitored with enough redundancy) and randomly picks some of them to start monitoring them.
In the future, this random picking will be replaced by a smarter algorithm.
Different options can be specified, like the monitor's `ID`, the maximum number of devices to take care of monitoring, the minimum redundancy, etc.:
<details><summary><b>$ go run monitor-assign.go -id 12345 -maxDevs 5 -minMons 3</b> (click here to see the whole content)</summary>
<p>
```
Initializing...
Using ID 12345
Setting timestamp to 1560419260
Updating globalAssign...
Adding device 35578 from cnmlDevices into globalAssign
Adding device 35580 from cnmlDevices into globalAssign
Adding device 41236 from cnmlDevices into globalAssign
Adding device 52800 from cnmlDevices into globalAssign
Adding device 53410 from cnmlDevices into globalAssign
Adding device 55625 from cnmlDevices into globalAssign
Adding device 58266 from cnmlDevices into globalAssign
Adding device 66287 from cnmlDevices into globalAssign
Adding device 67954 from cnmlDevices into globalAssign
Adding device 69514 from cnmlDevices into globalAssign
Adding device 74780 from cnmlDevices into globalAssign
Adding device 74943 from cnmlDevices into globalAssign
Adding device 75036 from cnmlDevices into globalAssign
Adding device 75038 from cnmlDevices into globalAssign
Adding device 75651 from cnmlDevices into globalAssign
Adding device 92844 from cnmlDevices into globalAssign
globalAssign updated!
Initialization done. Entering infinite loop...
Setting timestamp to 1560419265
Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!
Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Ended assignation list sanitization...
Reassignation of devices
0 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
16 devices unassigned
Picking 1 nodes randomly
1 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419270
Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!
Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Ended assignation list sanitization...
Reassignation of devices
1 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
15 devices unassigned
Picking 1 nodes randomly
2 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419275
Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!
Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Monitor 12345 found, keeping it for device 75651
Ended assignation list sanitization...
Reassignation of devices
2 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
14 devices unassigned
Picking 1 nodes randomly
3 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419280
Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!
Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Monitor 12345 found, keeping it for device 75036
Monitor 12345 found, keeping it for device 75651
Ended assignation list sanitization...
Reassignation of devices
3 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
13 devices unassigned
Picking 1 nodes randomly
4 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419285
Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!
Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Monitor 12345 found, keeping it for device 75036
Monitor 12345 found, keeping it for device 75038
Monitor 12345 found, keeping it for device 75651
Ended assignation list sanitization...
Reassignation of devices
4 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Assigning 1 new devices
12 devices unassigned
Picking 1 nodes randomly
5 devices currently assigned to this monitor
Exporting the new assigned devices list
Setting timestamp to 1560419290
Managing the monitors list...
I am monitor 12345
1 monitors registered in the database:
12345
Updating globalAssign...
globalAssign updated!
Sanitizing the assignation list...
Getting the current monitors list...
Updating the current cnml...
Monitor 12345 found, keeping it for device 52800
Monitor 12345 found, keeping it for device 75036
Monitor 12345 found, keeping it for device 75038
Monitor 12345 found, keeping it for device 75651
Monitor 12345 found, keeping it for device 92844
Ended assignation list sanitization...
Reassignation of devices
5 devices currently assigned to this monitor (maximum: 5 devices)
Updating the current cnml...
Not assigning any new device
```
</p>
</details>
<p>
`monitor-assign` not only cares about assigning itself the devices to monitor, but also pushes this information to AntidoteDB, so that other monitors can indirectly coordinate and pick the right devices to monitor.
Additionally, it periodically sanitizes the global assignation in AntidoteDB, by pruning assignations from monitors that are not in the system anymore (crashed, unresponsive, in another network partition...)
### Monitor the nodes' liveliness (ping RTT and TTL)
The `monitor-ping` pings the different devices the monitor is assigned periodically, and writes the information to AntidoteDB.
To have enough resolution for graphing, each device must be pinged *at least* every five minutes (and, ideally, this will happen simultaneously in other monitors, achieving the required redundancy).
The `monitor-ping` instance **must** use the same `ID` parameter as the local `monitor-assign` instance (in the future they will be merged into a single process):
<details><summary><b>$ go run monitor-ping.go -id 12345</b> (click here to see the whole content)</summary>
<p>
```
Initializing...
Using ID 12345
Initialization done. Entering infinite loop...
Pinging devices...
Pinging device 101994
10.1.27.13
I was asked to ping 10.1.27.13
false ==> offline
Pinging device 38720
10.1.26.97
I was asked to ping 10.1.26.97
true ==> online
Pinging device 42628
10.1.25.225
I was asked to ping 10.1.25.225
true ==> online
Pinging device 83865
10.1.25.130
10.228.207.130
I was asked to ping 10.1.25.130
true ==> online
Pinging device 87503
10.1.25.194
I was asked to ping 10.1.25.194
true ==> online
Pinging devices...
Pinging device 101994
10.1.27.13
I was asked to ping 10.1.27.13
false
Pinging device 38720
10.1.26.97
I was asked to ping 10.1.26.97
```
</p>
</details>
#### Note
Prior to running the program, a system setting must be configured:
```bash
$ sudo sysctl -w net.ipv4.ping_group_range="0 2147483647"
```
as per this note on Linux support:
```[...] this library attempts to send an "unprivileged" ping via UDP. On Linux, this must be enabled by setting [...]```
### Monitor the nodes' network traffic (SNMP) [WiP]
The `monitor-snmp` periodically asks the different devices the monitor is assigned periodically for their [SNMP information](https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol) to get details about their interfaces and the inbound/outbound traffic.
To have enough resolution for graphing, each device must be probed *at least* every five minutes (and, ideally, this will happen simultaneously in other monitors, achieving the required redundancy).
The `monitor-snmp` instance **must** use the same `ID` parameter as the local `monitor-assign` instance (in the future they will be merged into a single process).
Development of this piece of code is WiP.
## Data structures in AntidoteDB
### Devices⇔Monitors assignation
The primary data source for this application is the CNML file. The `monitor-fetch` application parses the specified CNML file and pushes its contents to AntidoteDB. There is a single `monitor-fetch` instance, and its writes/updates are __authoritative__.
In AntidoteDB, the data are structured as follows (some structures are shared with the *Monitoring data*, described below):
#### guifi (bucket)
The `guifi` bucket contains the lists of monitors and network devices to be monitored:
##### guifi (bucket) => devices (set)
The `devices` *set* in the `guifi` *bucket* is an `array` of `strings`, each `string` containing the `ID` of a Guifi.net device. For example:
```bash
$ curl localhost:3000/set/read/guifi/devices
["22110","26932","38720","40605","40962","41175","42331","42626","42627","42628",
"46654","46656","47103","48030","51580","57728","59001","60415","64962","64963",
"64965","64966","65291","65720","72843","73952","79715","81297","82096","82097",
"82098","82099","82103","82104","82105","82111","83865","85877","87503","90228",
"92032","92802","92803","92804","94210","94965","96225","96676","96684"]
```
##### guifi (bucket) => monitors (set)
The `monitors` *set* in the `guifi` *bucket* is an `array` of `strings`, each `string` containing the `ID` of a Guifi.net monitor. For example:
```bash
$ curl localhost:3000/set/read/guifi/monitors
["a45632","a47363", "21435"]
```
When started, each of the monitoring instances register to the system by adding their `ID` to this *set*.
##### guifi (bucket) => checksum (LWW<sup>1</sup> register)
The `checksum` *LWW register* in the `guifi` *bucket* is a `strings` containing the *SHA256 checksum* of the CNML data fetched from the Guifi.net website and pushed to the database. For example:
```bash
$ curl localhost:3000/register/read/guifi/checksum
35aaa826b841ed412897691bb1f50278d742ef9a76da9750a8ae509d3b01f8ee
```
#### device-i (bucket)
The `device-i` bucket, where `i` is the numeric `ID` of a device in the `guifi/devices` set, contains the information about a Guifi.net device:
##### device-i (bucket) => ipv4s (set)
The `ipv4s` *set* in the `device-i` *bucket* is an `array` of `strings`, each `string` containing an IPv4 address of the device. For example:
```bash
$ curl localhost:3000/set/read/device-26932/ipv4s
["10.139.37.226","172.25.40.188","172.25.40.189"]
```
##### device-i (bucket) => monitors (set)
The `monitors` *set* in the `device-i` *bucket* is an `array` of `strings`, each `string` containing the ID of a monitor the device is assigned to (i.e. the `ID` of a monitor that is in charge of monitoring the device). For example:
```bash
$ curl localhost:3000/set/read/device-26932/monitors
["a45632","a47363","21435"]
```
##### device-i (bucket) => graphserver (LWW register)
The `graphserver` *LWW register* in the `device-i` *bucket* is a `string` containing the ID of a monitor the device is assigned to **in the Guifi.net** website (i.e., not automatically assigned by the monitoring application, but done manually on the Guifi.net website, and included in the CNML). For example:
```bash
$ curl localhost:3000/register/read/device-26932/graphserver
71808
```
### Monitoring data
The collected monitoring data are stored in AntidoteDB using the following structure and data types (some structures are shared with the *Devices⇔Monitors assignation* sata, described above:
#### device-i (bucket)
The `device-i` bucket, where `i` is the numeric `ID` of a device in the `guifi/devices` set, contains the monitoring data collected about a Guifi.net device:
##### device-i (bucket) => rawping (map)
The `rawping` *map* in the `device-i` *bucket* is a collection of nested maps where the raw ping data are stored.
The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawping/
{["2018-12-31","2019-01-01","2019-01-02","2019-01-03","2019-01-04","2019-01-05","2019-01-06", ... ,"2019-03-13","2019-03-14"]}
```
##### device-i (bucket) => rawping (map) => year-month-day (map)
The `year-month-day` *map* in the `rawping` *map* in the `device-i` *bucket* contains the raw ping data stored during a given day.
The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawping/2019-03-14/
{["00-00-00-21435","00-00-00-a45632","00-00-00-a47363","00-05-00-21435","00-05-00-a45632","00-05-00-a47363","00-10-00-21435","00-10-00-a45632","00-10-00-a47363","23-50-00-21435","23-50-00-a45632","23-50-00-a47363","23-55-00-21435","23-55-00-a45632","23-55-00-a47363"]}
```
##### device-i (bucket) => rawping (map) => year-month-day (map) => hour-minute-second-monitorID (set)
The `year-month-day` *map* in the `rawping` *map* in the `device-i` *bucket* contains the raw ping data captured at a given moment by a specific monitor.
The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawping/2019-03-14/23-55-00-a45632
{["12452","9873","10347","12906","96991","62"]}
```
where the 5 first numbers correspond to the ping RTT, in nanoseconds, and the last one to the TTL count.
##### device-i (bucket) => rawsnmp (map)
The `rawsnmp` *map* in the `device-i` *bucket* is a collection of nested maps where the raw SNMP data are stored.
The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawsnmp/
{["2018-12-31","2019-01-01","2019-01-02","2019-01-03","2019-01-04","2019-01-05","2019-01-06", ... ,"2019-03-13","2019-03-14"]}
```
##### device-i (bucket) => rawsnmp (map) => year-month-day (map)
The `year-month-day` *map* in the `rawsnmp` *map* in the `device-i` *bucket* contains the raw SNMP data stored during a given day.
The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawsnmp/2019-03-14/
{["00-00-00-21435","00-00-00-a45632","00-00-00-a47363","00-05-00-21435","00-05-00-a45632","00-05-00-a47363","00-10-00-21435","00-10-00-a45632","00-10-00-a47363","23-50-00-21435","23-50-00-a45632","23-50-00-a47363","23-55-00-21435","23-55-00-a45632","23-55-00-a47363"]}
```
##### device-i (bucket) => rawping (map) => year-month-day (map) => hour-minute-second-monitorID (set)
The `year-month-day` *map* in the `rawsnmp` *map* in the `device-i` *bucket* contains the raw SNMP data captured at a given moment by a specific monitor.
The following call will not work<sup>2</sup>, but gives an example of the data structure:
```bash
$ curl localhost:3000/map/list/device-26932/rawsnmp/2019-03-14/23-55-00-a45632
{["sfp1", "0", "320", "ether1", "0", "0", "wlan1", "72752170", "194023223",
"ether3", "4211890690", "3457835469", "ether4", "1481996123", "3715009965",
"ether5", "3986712032", "2292081157", "ether6", "6036", "43256812", "wlan5",
"3253125075", "4192397953", "wlan6", "1438160383", "430948927", "ether9", "0",
"0", "ether10", "0", "0", "lan", "75134070", "158936718", "wlan2", "0", "0",
"wlan3", "1224542542", "3312721186", "wlan4", "0", "6703436", "sjd",
"166864741", "6605882", "bel", "0", "6605882", "qmp", "0", "0", "wlan7",
"2064155005", "1601779739"]}
```
where the data are ordered, sequentially, as "Interface name", "RxBytes", "TxBytes", etc.
---
<sup>1</sup> LWW: last writer wins
<sup>2</sup> The REST API does not support nested maps (but the Go client does)
<?xml version="1.0"?>
<cnml version="0.1" server_id="1" server_url="http://guifi.net" generated="20190606 0703">
<class network_description="detail" mapping="y"/>
<network nodes="19" devices="63" ap="10" client="4" services="4" links="21">
<zone id="46433" parent_id="2436" title="Zona Universit&#xE0;ria - Campus Nord UPC" time_zone="+01 2 2" graph_server="78107" created="20120306 0348" updated="20160527 1044" zone_nodes="19" box="2.109461,41.382283,2.121563,41.391813" access_points="10" clients="4" devices="63" services="4" links="21">
<node id="28121" title="BCN-UPC-DSG" lat="41.389663" lon="2.113056" antenna_elevation="15" status="Working" created="20100211 1141" updated="20131015 0416" access_points="3" devices="5" links="5">
<device id="22110" mainipv4="10.139.37.225" title="BCN-UPC-DSGST1" type="radio" status="Working" created="20100518 0102" updated="20150122 1247" firmware="RouterOSv5.x" name="Routerboard 433">
<radio id="0" device_id="22110" ssid="BCNUPCDSG-UPCH" mode="ap" protocol="802.11a" channel="5240" antenna_angle="30" antenna_gain="19" clients_accepted="No" snmp_name="wlan1">
<interface id="30139" type="wLan/Lan" mac="00:0C:42:61:AD:8A" ipv4="10.139.37.225" mask="255.255.255.224">
<link id="45233" linked_device_id="40246" linked_node_id="21150" linked_interface_id="70559" link_type="ap/client" link_status="Building"/>
</interface>
<interface id="30138" type="wdsBCNUPCDSG-UPCH" mac="00:0C:42:61:AD:8A" ipv4="172.25.38.129" mask="255.255.255.252">
<link id="30624" linked_device_id="26918" linked_node_id="30132" linked_interface_id="50942" link_type="wds" link_status="Working"/>
</interface>
<interface id="30138" type="wdsBCNUPCDSG-UPCH" mac="00:0C:42:61:AD:8A" ipv4="172.25.35.170" mask="255.255.255.252">
<link id="45627" linked_device_id="40605" linked_node_id="49474" linked_interface_id="71061" link_type="wds" link_status="Working"/>
</interface>
</radio>
<interface id="30139" type="wLan/Lan" mac="00:0C:42:61:AD:8A" ipv4="10.139.37.225" mask="255.255.255.224">
<link id="30840" linked_device_id="27495" linked_node_id="28121" linked_interface_id="51819" link_type="cable" link_status="Planned"/>
</interface>
<interface id="30138" type="wdsBCNUPCDSG-UPCH" mac="00:0C:42:61:AD:8A" ipv4="172.25.38.129" mask="255.255.255.252"/>
<interface id="30138" type="wdsBCNUPCDSG-UPCH" mac="00:0C:42:61:AD:8A" ipv4="172.25.35.170" mask="255.255.255.252"/>
<interface id="125973" type="Lan" mac="00:00:00:00:00:0B" ipv4="10.139.37.254" mask="255.255.255.224">
<link id="121907" linked_device_id="72843" linked_node_id="28121" linked_interface_id="132763" link_type="cable" link_status="Working"/>
</interface>
</device>
<device id="26932" mainipv4="10.139.37.226" title="BCN-UPC-DSG-BgH" type="radio" status="Working" created="20110105 0828" updated="20120727 1136" firmware="AirOsv52" name="AirMaxM5 Bullet/PwBrg/AirGrd/NanoBr">
<radio id="0" device_id="26932" ssid="BCNUPCDSGBgH" mode="ap" protocol="802.11n" channel="5280" antenna_angle="6" antenna_gain="22" clients_accepted="No" snmp_name="ath0">
<interface id="50965" type="wds/p2p" mac="00:15:6D:1E:3E:35" ipv4="172.25.40.188" mask="255.255.255.248">
<link id="30203" linked_device_id="26918" linked_node_id="30132" linked_interface_id="50942" link_type="wds" link_status="Working"/>
</interface>
</radio>
<interface id="50966" type="Lan" mac="00:15:6D:1E:3E:35" ipv4="10.139.37.226" mask="255.255.255.224"/>
<interface id="50968" type="eth0" mac="00:00:00:00:00:00" ipv4="172.25.40.189" mask="255.255.255.248">
<link id="30204" linked_device_id="22110" linked_node_id="28121" linked_interface_id="50967" link_type="cable" link_status="Working"/>
</interface>
<interface id="50965" type="wds/p2p" mac="00:15:6D:1E:3E:35" ipv4="172.25.40.188" mask="255.255.255.248"/>
</device>
<device id="27495" mainipv4="10.139.37.227" title="carmen.lsi.upc.edu" type="server" status="Reserved" created="20110201 0431" updated="20110212 0659">
<interface id="51819" type="Lan" mac="00:00:00:00:00:00" ipv4="10.139.37.227" mask="255.255.255.224">
<link id="30840" linked_device_id="22110" linked_node_id="28121" linked_interface_id="30139" link_type="cable" link_status="Planned"/>
</interface>
</device>
<device id="37425" mainipv4="" title="BCN-UPC-DSG-Srv" type="server" status="Planned" created="20120120 0432" updated="20120120 0446"/>
<device id="72843" mainipv4="10.139.37.229" title="BCN-UPC-DSG-NB" type="radio" status="Testing" created="20150114 0715" updated="20151214 0145" firmware="AirOsv5.x" name="AirMaxM5 Bullet/PwBrg/AirGrd/NanoBr">
<radio id="0" device_id="72843" ssid="UPCNord-ZFranca204" mode="ap" protocol="802.11n" channel="5000" antenna_angle="6" antenna_gain="25" clients_accepted="No" snmp_name="ath0">
<interface id="131937" type="wdsUPCNord-ZFranca204" mac="04:18:D6:54:EF:DC" ipv4="172.25.32.65" mask="255.255.255.252">
<link id="121608" linked_device_id="72840" linked_node_id="42179" linked_interface_id="131935" link_type="wds" link_status="Working"/>
</interface>
</radio>
<interface id="132763" type="Lan" mac="04:18:D6:54:EF:DC" ipv4="10.139.37.229" mask="255.255.255.224">
<link id="121907" linked_device_id="22110" linked_node_id="28121" linked_interface_id="125973" link_type="cable" link_status="Working"/>
</interface>
<interface id="131937" type="wdsUPCNord-ZFranca204" mac="04:18:D6:54:EF:DC" ipv4="172.25.32.65" mask="255.255.255.252"/>
</device>
</node>
<node id="49335" title="BCNGranVia204b" lat="41.368741" lon="2.142189" status="Working" created="20120620 0147" updated="20190115 1020" devices="7">
<device id="42177" mainipv4="10.228.205.129" title="BCNGranVia204bRB1" type="radio" status="Inactive" created="20120620 0150" updated="20190115 1127" firmware="qMp" name="Alix1">
<radio id="0" device_id="42177" ssid="UPC-LLcerda" mode="ad-hoc" protocol="802.11a" channel="5000" antenna_angle="30" antenna_gain="14" clients_accepted="Yes" snmp_name=""/>
<interface id="73313" type="Lan" mac="02:CA:FF:EE:BA:BE" ipv4="10.228.205.129" mask="255.255.255.240"/>
</device>
<device id="89332" mainipv4="10.1.12.193" title="BCNGranVia204bNB1" type="radio" status="Working" created="20161016 1225" updated="20161016 1228" firmware="qMp" name="AirMaxM5 Rocket/Nano/Loco">
<radio id="0" device_id="89332" ssid="GSBCNGrnV204bRd6MESH" mode="mesh" protocol="802.11b" antenna_gain="14" clients_accepted="No" snmp_name="br-lan"/>
<interface id="182840" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.12.193" mask="255.255.255.224"/>
</device>
<device id="101781" mainipv4="10.1.26.193" title="BCNGranVia204bRd6" type="radio" status="Planned" created="20180915 0445" firmware="qMp" name="Apu">
<radio id="0" device_id="101781" ssid="UPCBCNGrnV204bRd6MESH" mode="mesh" protocol="802.11b" antenna_gain="14" clients_accepted="No" snmp_name=""/>
<interface id="217770" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.26.193" mask="255.255.255.224"/>
</device>
<device id="85519" mainipv4="10.1.11.1" title="BCNGranVia204bPB1" type="radio" status="Working" created="20160502 1048" updated="20161016 1132" firmware="qMp" name="AirMaxM5 Rocket/Nano/Loco">
<radio id="0" device_id="85519" ssid="GSBCNGrnV204bRd4MESH" mode="mesh" protocol="802.11b" antenna_gain="14" clients_accepted="No" snmp_name="ath0"/>
<interface id="172295" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.11.1" mask="255.255.255.224"/>
</device>
<device id="103535" mainipv4="10.1.24.33" title="BCNGranVia204bRd7" type="radio" status="Working" created="20190115 1029" updated="20190115 1126" firmware="qMp" name="AirMaxM5 Rocket/Nano/Loco">
<radio id="0" device_id="103535" ssid="UPCBCNGrnV204bRd7MESH" mode="mesh" protocol="802.11b" antenna_gain="14" clients_accepted="No" snmp_name="br-lan"/>
<interface id="222607" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.24.33" mask="255.255.255.224"/>
</device>
<device id="89330" mainipv4="10.1.12.129" title="BCNGranVia204bNL1" type="radio" status="Working" created="20161016 1206" updated="20161016 1212" firmware="AirOsv5.x" name="AirMaxM5 Rocket/Nano/Loco">
<radio id="0" device_id="89330" ssid="GSBCNGrnV204bRd6MESH" mode="mesh" protocol="802.11b" antenna_gain="14" clients_accepted="No" snmp_name="ath0"/>
<interface id="182836" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.12.129" mask="255.255.255.224"/>
</device>
<device id="89331" mainipv4="10.1.12.161" title="BCNGranVia204bNS1" type="radio" status="Working" created="20161016 1215" updated="20161016 1224" firmware="qMp" name="AirMaxM5 Rocket/Nano/Loco">
<radio id="0" device_id="89331" ssid="GSBCNGrnV204bRd6MESH" mode="mesh" protocol="802.11b" antenna_gain="14" clients_accepted="No" snmp_name="br-lan"/>
<interface id="182838" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.12.161" mask="255.255.255.224"/>
</device>
</node>
<node id="57757" title="BCNMarquesDeMulhacen" lat="41.390357" lon="2.120936" antenna_elevation="30" status="Inactive" created="20130408 0614" updated="20140417 0422"/>
<node id="53090" title="UPC-Castelldefels" lat="41.275294" lon="1.986569" antenna_elevation="20" status="Working" created="20121024 0505" updated="20140428 1124" access_points="3" devices="5">
<device id="47103" mainipv4="10.228.206.49" title="UPC-EESAB-NS1" type="radio" status="Working" created="20121106 1111" updated="20140429 1043" firmware="qMpv1" name="AirMaxM5 Rocket/Nano/Loco">&amp;nbsp;<radio id="0" device_id="47103" ssid="qMp" mode="mesh" protocol="802.11n" channel="5700" antenna_gain="14" clients_accepted="No" snmp_name="br-lan"><interface id="96737" type="wLan/Lan" mac="02:CA:FF:EE:BA:BE" ipv4="10.228.206.49" mask="255.255.255.240"/></radio><interface id="96737" type="wLan/Lan" mac="02:CA:FF:EE:BA:BE" ipv4="10.228.206.49" mask="255.255.255.240"><link id="73071" linked_device_id="64967" linked_node_id="53090" linked_interface_id="106176" link_type="cable" link_status="Working"/></interface></device>
<device id="64967" mainipv4="10.228.206.50" title="UPC-EESAB-NB1" type="radio" status="Planned" created="20140429 1055" firmware="AirOsv52" name="AirMaxM5 Rocket/Nano/Loco">&amp;nbsp;<radio id="0" device_id="64967" ssid="UPCPCSBNB1AP0" mode="ap" protocol="802.11n" channel="5000" antenna_angle="120" antenna_gain="14" clients_accepted="No" snmp_name="ath0"/><interface id="106176" type="Lan" mac="00:00:00:00:00:00" ipv4="10.228.206.50" mask="255.255.255.240"><link id="73071" linked_device_id="47103" linked_node_id="53090" linked_interface_id="96737" link_type="cable" link_status="Working"/></interface></device>
<device id="46656" mainipv4="10.228.206.33" title="UPC-EETAC-NS1" type="radio" status="Working" created="20121024 0510" updated="20140429 1043" firmware="qMpv1" name="AirMaxM5 Rocket/Nano/Loco">&amp;nbsp;<radio id="0" device_id="46656" ssid="qMp" mode="ad-hoc" protocol="802.11a" channel="5000" antenna_gain="14" clients_accepted="Yes" snmp_name="br-lan"><interface id="79883" type="wLan/Lan" mac="02:CA:FF:EE:BA:BE" ipv4="10.228.206.33" mask="255.255.255.240"/></radio><interface id="79883" type="wLan/Lan" mac="02:CA:FF:EE:BA:BE" ipv4="10.228.206.33" mask="255.255.255.240"><link id="73069" linked_device_id="64965" linked_node_id="53090" linked_interface_id="106170" link_type="cable" link_status="Working"/><link id="73070" linked_device_id="64966" linked_node_id="53090" linked_interface_id="106173" link_type="cable" link_status="Working"/></interface></device>
<device id="64965" mainipv4="10.228.206.34" title="UPC-EETAC-Rocket" type="radio" status="Working" created="20140429 1045" updated="20140604 0242" firmware="AirOsv52" name="AirMaxM5 Bullet/PwBrg/AirGrd/NanoBr">&amp;nbsp;<radio id="0" device_id="64965" ssid="UPCPCTCRcktAP0" mode="ap" protocol="802.11n" channel="5000" antenna_angle="120" antenna_gain="14" clients_accepted="No" snmp_name="ath0"/><interface id="106170" type="Lan" mac="00:00:00:00:00:00" ipv4="10.228.206.34" mask="255.255.255.240"><link id="73069" linked_device_id="46656" linked_node_id="53090" linked_interface_id="79883" link_type="cable" link_status="Working"/></interface></device>
<device id="64966" mainipv4="10.228.206.35" title="UPC-EETAC-Alix" type="radio" status="Working" created="20140429 1051" updated="20140604 0243" firmware="kamikaze" name="Alix2">&amp;nbsp;<radio id="0" device_id="64966" ssid="UPCPCTClxAP0" mode="ap" protocol="802.11n" channel="5000" antenna_angle="120" antenna_gain="14" clients_accepted="Yes" snmp_name="ath0"/><interface id="106173" type="Lan" mac="00:00:00:00:00:00" ipv4="10.228.206.35" mask="255.255.255.240"><link id="73070" linked_device_id="46656" linked_node_id="53090" linked_interface_id="79883" link_type="cable" link_status="Working"/></interface></device>
</node>
<node id="47678" title="UPC-CN-A1-Terrat" lat="41.387712" lon="2.111575" status="Reserved" created="20120425 0549" updated="20180618 1121" devices="1">
<device id="40216" mainipv4="10.1.26.33" title="UPC-CN-A1-Alix" type="radio" status="Reserved" created="20120425 0551" updated="20180829 0747" firmware="qMp" name="Alix2">
<radio id="0" device_id="40216" ssid="UPCPCCN1lxMESH" mode="mesh" protocol="802.11ac" channel="5000" antenna_gain="14" clients_accepted="No" snmp_name="wlan0"/>
<interface id="217224" type="Lan" mac="02:CA:FF:EE:BA:BA" ipv4="10.1.26.33" mask="255.255.255.224"/>
</device>
</node>
<node id="49737" title="UPC-CN-B3" lat="41.388563" lon="2.111585" antenna_elevation="15" status="Working" created="20120703 1201" updated="20160519 0348" devices="1">
<device id="42627" mainipv4="10.1.26.65" title="UPC-CN-B3-NS" type="radio" status="Working" created="20120703 1202" updated="20160519 0413" firmware="qMp" name="AirMaxM5 Rocket/Nano/Loco">
<radio id="0" device_id="42627" ssid="guifi.net/UPC-CN-B3" mode="mesh" protocol="802.11n" channel="5700" antenna_gain="14" clients_accepted="No" snmp_name="br-lan"/>
<interface id="173544" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.26.65" mask="255.255.255.224"/>
</device>
</node>
<node id="107286" title="UPC-CN-C5-Terrat" lat="41.389308" lon="2.112800" antenna_elevation="20" status="Working" created="20180510 1116" updated="20190114 0733" devices="2">
<device id="102133" mainipv4="10.1.24.1" title="UPC-CN-C5-ER-X-SFP" type="radio" status="Working" created="20181009 0715" updated="20190114 0805" firmware="EdgeOS_v1.6" name="EdgePoint R6">
<interface id="218697" type="br-lan" mac="FC:EC:DA:75:03:CE" ipv4="10.1.24.1" mask="255.255.255.224">
<link id="156335" linked_device_id="90228" linked_node_id="107286" linked_interface_id="222571" link_type="cable" link_status="Working"/>
</interface>
</device>
<device id="90228" mainipv4="10.1.24.2" title="UPC-CN-C6-Terrat-Rocket-bcee" type="radio" status="Working" created="20161130 1247" updated="20190114 0803" firmware="qMp" name="AirMaxM5 Rocket/Nano/Loco">
<radio id="0" device_id="90228" ssid="qMp-UPC-CN-C5-Terrat-R" mode="mesh" protocol="802.11n" channel="5500" antenna_gain="14" clients_accepted="No" snmp_name="br-lan"/>
<interface id="222571" type="Lan" mac="80:2A:A8:7E:BC:EE" ipv4="10.1.24.2" mask="255.255.255.224"/>
</device>
</node>
<node id="54181" title="UPC-CN-C6-102" lat="41.389620" lon="2.112854" antenna_elevation="7" status="Working" created="20121203 1204" updated="20160720 0406" clients="3" devices="3">
<device id="87503" mainipv4="10.1.25.194" title="UPC-CN-C6-102-rd0052" type="server" status="Working" created="20160720 0407">
<interface id="177819" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.25.194" mask="255.255.255.224">
<link id="137713" linked_device_id="48030" linked_node_id="54181" linked_interface_id="137333" link_type="cable" link_status="Working"/>
</interface>
</device>
<device id="48030" mainipv4="10.1.25.193" title="UPC-CN-C6-102-3814" type="radio" status="Working" created="20121203 1206" updated="20160720 0408" firmware="qMp" name="Alix2">
<radio id="0" device_id="48030" ssid="qMp-UPC-CN-C6-102-MESH" mode="mesh" protocol="802.11n" channel="5000" antenna_gain="14" clients_accepted="No" snmp_name="wlan0"/>
<interface id="137333" type="Lan" mac="00:80:48:75:32:2C" ipv4="10.1.25.193" mask="255.255.255.224">
<link id="137713" linked_device_id="87503" linked_node_id="54181" linked_interface_id="177819" link_type="cable" link_status="Working"/>
</interface>
</device>
<device id="97899" mainipv4="" title="MAIChuelvaIslaChicaRd2" type="radio" status="Planned" created="20180131 0300" updated="20180131 0330" firmware="n/a" name="Generic/Other">IP&amp;nbsp;&lt;em&gt;10.38.140.3&lt;/em&gt;/&lt;em&gt;255.255.255.224&lt;/em&gt;&lt;br /&gt;&#xD;
54181-UPC, UPCCNC6102<radio id="0" device_id="97899" ssid="IberiaMChlvslChcRd2CPE1" mode="client" protocol="802.11b" antenna_angle="60" antenna_gain="27" clients_accepted="No" snmp_name=""/><radio id="1" device_id="97899" ssid="IberiaMChlvslChcRd2CPE0" mode="client" protocol="802.11b" antenna_angle="60" antenna_gain="27" clients_accepted="No" snmp_name=""/><radio id="2" device_id="97899" ssid="UPCMChlvslChcRd2CPE2" mode="client" protocol="802.11b" antenna_angle="60" antenna_gain="27" clients_accepted="No" snmp_name=""/></device>
</node>
<node id="49736" title="UPC-CN-C6-213" lat="41.389592" lon="2.113173" status="Working" created="20120703 1158" updated="20151203 0440" devices="1">
<device id="42626" mainipv4="10.1.26.161" title="UPC-CN-C6-213-Rd1" type="radio" status="Working" created="20120703 1159" updated="20180829 0755" firmware="qMp" name="AirMaxM5 Rocket/Nano/Loco">
<radio id="0" device_id="42626" ssid="UPCPCCNC6213Rd1MESH" mode="mesh" protocol="802.11ac" channel="5000" antenna_gain="14" clients_accepted="No" snmp_name="br-lan"/>
<interface id="217227" type="Lan" mac="00:00:00:00:00:00" ipv4="10.1.26.161" mask="255.255.255.224"/>
</device>
</node>
<node id="49474" title="UPC-CN-C6-E104" lat="41.389688" lon="2.113007" status="Working" created="20120625 0608" updated="20151210 0649" access_points="1" devices="17" links="15" services="4">
<device id="83865" mainipv4="10.1.25.130" title="UPC-CN-C6-E104-Portal-OpenWrt-BMX6" type="radio" status="Working" created="20160225 0342" updated="20190110 0114" firmware="qMp" name="Generic x86 (qMp no WiFi)">
<interface id="167519" type="Lan" mac="A0:F3:C1:FA:C0:2D" ipv4="10.1.25.130" mask="255.255.255.224">
<link id="156277" linked_device_id="103461" linked_node_id="49474" linked_interface_id="222443" link_type="cable" link_status="Working"/>
<link id="156300" linked_device_id="103462" linked_node_id="49474" linked_interface_id="222481" link_type="cable" link_status="Working"/>