1
0
Fork 0

Compare commits

...

21 Commits

@ -8,11 +8,12 @@ TODO: Describe, what the thesis is about maybe.
Compilation
---
The compilation depends on VeraPDF v1.16.1, some subset of TeX Live, and a Make implementation.
The compilation depends on VeraPDF v1.16.1, Graphviz, some subset of TeX Live, and a Make implementation.
```sh
(cd img/graphviz-fail && make)
cd en
make
make -B thesis.pdf verapdf_report.xml
```
Acknowledgements
@ -46,4 +47,4 @@ Language conventions
- Non-Oxford British spelling (neighb_ou_r, rational_ise_)
- Only first letter in title is capital, other are not (unless they are titles themselves)
- Figures are referenced as "… on Figure~NUM" (i.e. capital letter, without abbreviating)
- Figures are referenced as "… on figure~NUM" (i.e. non-capital letter, without abbreviating)

@ -12,8 +12,13 @@
\begin{document}
%% Nezapomeňte upravit abstrakt.xmpdata.
Toto je ukázkový abstrakt.
Síťoví administrátoři potřebují mít přehled o stavu své sítě. Link-state
protokoly jako OSPF sice přehled o topologii sítě mají, ale až dosud
neexistoval jednoduchý způsob, jak jej zobrazit administrátorovi. Náš projekt
Birdvisu zobrazuje topologii, jak ji zná routovací daemon BIRD. Náš přístup
umožňuje k topologii dále přidávat další informace, díky čemuž je možné
topologie analyzovat a tyto analytické schopnosti dále rozšiřovat. Přestože
ještě nejsou implementovány všechny funkce, pomohlo Birdvisu odhalit několik
chyb v konfiguraci komunitní sítě propojující asi 1600 lidí.
\end{document}

@ -1,5 +1,5 @@
% Metadata k uložení do PDF, podrobnější popis viz dokumentace balíčku pdfx.
\Author{Jméno Příjmení}
\Title{Název práce}
\Author{Pavel Turinský}
\Title{Vizualizace topologie OSPF}
\Publisher{Univerzita Karlova}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

@ -0,0 +1,289 @@
\documentclass{beamer}
\usetheme{Madrid}
% Ref: https://tex.stackexchange.com/a/692
\setbeamertemplate{navigation symbols}{}
% We may as well create a PDF/A, why not. (I am too lazy to invent my
% own header, instead I just pick line from the thesis' one :-))
\usepackage[a-2u]{pdfx}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage{xcolor}
\usepackage{listings}
\hypersetup{unicode}
\hypersetup{breaklinks=true}
\def\uv#1{``#1''}
\title{Visualising OSPF topology}
\subtitle{Motivation and design of Birdvisu} %FIXME?
\author{Pavel Turinský}
\date{7 September 2023}
%\date{07-09-2023} % Looks weird imho :-/
\begin{document}
\begin{frame}
\titlepage
\end{frame}
\iffalse % Maybe drop, in that case, comment the next line.
%\else
\begin{frame}
\frametitle{Outline}
\begin{itemize}
\item Introduction
\begin{itemize}
\item What is Birdvisu
\item Reasons for creating Birdvisu
\item Goals
\end{itemize}
% intro:
%% what
%% why (comparison)
%% goals
\item Technologies
\begin{itemize}
\item OSPF overview
\item Interaction with BIRD
\end{itemize}
% tech stack
%% OSPF summary + history
%% BIRD: why and how
%%% the dump format
%%% note gennet
\item Design
\begin{itemize}
\item Retrieving topologies
\item Annotation
\item Drawing
\end{itemize}
% design
%% the three phases
\item Results
\begin{itemize}
\item Small networks
\item Large: czela.net
\end{itemize}
% results
%% czela,net
%%% known deficiencies
\item Future
% future?
%% exports, integration
%% saving layouts
% gennet?
\end{itemize}
\end{frame}
\fi
%TODO: slide about Birdvisu is, very highlevel
\begin{frame}
\frametitle{Project goals}
The Birdvisu project aims to present the network topology, as known
by OSPF, to the administrator and allow them to analyse it.
\bigskip
Goals:
\begin{itemize}
\item As independent on other services as possible
\item Easy deployment
\begin{itemize}
\item Runnable on admin's laptop
\end{itemize}
\item No changes to other hosts required
\item It should be easy to create new analysis tools
\item Target: administrators of homelabs to middle-sized systems
\end{itemize}
\medskip
To our knowledge, there is no such application yet.
\medskip
Birdvisu is implemented in Python 3 and Qt 6.
\end{frame}
% \begin{frame}
% %\frametitle{Why visualise/analyse topologies}
% \frametitle{Motivation and goals}
% Existing analysis/monitoring tools:
% \begin{itemize}
% \item Need to collect data on individual hosts,
% \item do may not have accurate data (network splits)
% \item or need to be deployed on a server
% \end{itemize}
% \dots yet in systems routed by OSPF each router knows all of this.
%
% \vfill
%
% The aim of Birdvisu is to present this information to
% administrators.
% \begin{itemize}
% \item single-host, easy-to-run, few dependencies on services
% \item Target: administrators of homelabs to middle-sized systems
% \end{itemize}
% \end{frame}
% TODO: wanted features?
%%% design
\begin{frame}
\frametitle{Birdvisu design}
% uwu uwu FIXME TODO
The program consists of three main steps:
\begin{itemize}
\item Obtaining the topologies
% shenanigans?
% non-matchability of uwu uwu.
\begin{itemize}
\item Reference (from file), current state
\item Representation: weighted directed multigraph
% \item Reference and current one merged into a single object
% \item Extracted from BIRD or loaded from saved files
% \item Networks can have various forms: orieiwnted weighted multigraph
\end{itemize}
\item Annotating
\begin{itemize}
\item Extending the topology with analysis results, other data, \dots
% \item Many single-purpose annotators
% \item e.g. compute topology differences, find shortest paths
\end{itemize}
\item Displaying the result
% own try of layouting alg
% each highlight has its StyleAnnotator
\begin{itemize}
\item Reduction of the topology to a simple graph
\item Highlight relevant annotator results
\medskip
\item Alternatively export the annotated topology (in future)
% \item Use Qt's features: dragging, interaction
% \item Layout loaded from file or determined by ad-hoc
% algorithm
% \item Reuses Annotator design
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{OSPF}
\begin{itemize}
\item Link-state IGP: routers share information about the current state of the system
\item Long evolution (1989), multiple extensions, rather complex
\item Different versions for IPv4 and IPv6 routing
\begin{itemize}
\item Same idea, quite different internals
\end{itemize}
\end{itemize}
\bigskip
Instead of implementing OSPF ourselves, we extract the state from existing routing daemon.
\end{frame}
\begin{frame}
\frametitle{BIRD Internet Routing Daemon}
\begin{itemize}
\item Originally SW project at this faculty, now maintained by CZ.NIC
\item Experience from deployment at home, Dept{.} of Applied Mathematics
\item One of two maintained OSPF daemons for general-purpose HW %FIXME: check BrE
\begin{itemize}
\item future extensions more likely to be implemented
\end{itemize}
\end{itemize}
\bigskip
\begin{itemize}
\item Currently no machine-readable export
\begin{itemize}
\item The output for humans contains sufficient information
\end{itemize}
\item No dynamic output -- needs polling
\end{itemize}
% logo? snippet of output?
\end{frame}
\begin{frame}
\frametitle{Annotators}
\begin{itemize}
\item Can add arbitrary$^*$ data to vertices and edges
\begin{itemize}
\item Exportable in future
\end{itemize}
\item Can depend on each other
\item Idea: many simple and single-purpose annotators
\item Uses: analysis, providing additional information, \dots
\begin{itemize}
\item e.g. comparing topologies, finding shortest path DAGs
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Visualisation}
\begin{itemize}
\item Reuse Annotators for styling vertices and edges
\item Reduce topology to a simple graph by taking the most relevant edge
\begin{itemize}
\item lightest edge with positive cost
\end{itemize}
\item Layout can be loaded from a file
\begin{itemize}
\item New vertices placed to proximity of neighbours
\end{itemize}
\item Qt provides UI features: dragging, context menus
\end{itemize}
\end{frame}
% Results and examples
\begin{frame}
\frametitle{Small network example: Gennet}
\begin{center}
\includegraphics[keepaspectratio,height=0.7\textheight]{gennet.png}
\\
Highlighting differences from expectation on a test network (Gennet)
\end{center}
\end{frame}
\begin{frame}
\frametitle{Medium-sized network: Czela.net}
Community network system in Čelákovice, 45 routers, 210 networks (incl. external), about 1600 people
\begin{center}
\includegraphics[keepaspectratio,height=0.6\textheight]{czmess.png}
\\
Our layouting approach is not great without any initial placements.
\end{center}
\end{frame}
\begin{frame}
\frametitle{Fixing Czela.net}
\begin{center}
\includegraphics[keepaspectratio,height=0.7\textheight]{czbug.png}
\\
Misconfiguration, found after some dragging of vertices
\end{center}
\end{frame}
\begin{frame}
\begin{center}
\begin{Large}
Thank you!
\end{Large}
\end{center}
\end{frame}
\end{document}

@ -13,6 +13,13 @@
%% Do not forget to edit abstract.xmpdata.
This is an example abstract.
Network administrators need to be aware of the state of their network. While
link-state routing protocols like OSPF have the required information, there was
no easy way to present it to the administrator. To solve this problem, we
developed Birdvisu, a program to visualise the topology as seen by the BIRD
Internet Routing Daemon. Our approach allows the topology to be easily
annotated with other data, providing an extensible way of analysing the
topology. While not fully featured yet, Birdvisu helped discover several
misconfigurations in a community-run network connecting about 1600 people.
\end{document}

@ -1,5 +1,5 @@
% Metadata to be stored in PDF, see documentation of the pdfx package for more details.
\Author{Name Surname}
\Title{Thesis title}
\Author{Pavel Turinský}
\Title{Visualizing OSPF topology}
\Publisher{Charles University}

@ -74,6 +74,51 @@
abstract = {This memo documents version 2 of the OSPF protocol. OSPF is a link- state routing protocol. {[}STANDARDS-TRACK{]}},
}
@misc{rfc3101,
series = {Request for Comments},
number = 3101,
howpublished = {RFC 3101},
publisher = {RFC Editor},
doi = {10.17487/RFC3101},
url = {https://www.rfc-editor.org/info/rfc3101},
author = {Dr. Patrick W. Murphy},
title = {{The OSPF Not-So-Stubby Area (NSSA) Option}},
pagetotal = 33,
year = 2003,
month = jan,
abstract = {This memo documents an optional type of Open Shortest Path First (OSPF) area that is somewhat humorously referred to as a "not-so-stubby" area (or NSSA). NSSAs are similar to the existing OSPF stub area configuration option but have the additional capability of importing AS external routes in a limited fashion. The OSPF NSSA Option was originally defined in RFC 1587. The functional differences between this memo and RFC 1587 are explained in Appendix F. All differences, while expanding capability, are backward-compatible in nature. Implementations of this memo and of RFC 1587 will interoperate. {[}STANDARDS-TRACK{]}},
}
@misc{rfc6549,
series = {Request for Comments},
number = 6549,
howpublished = {RFC 6549},
publisher = {RFC Editor},
doi = {10.17487/RFC6549},
url = {https://www.rfc-editor.org/info/rfc6549},
author = {Acee Lindem and Abhay Roy and Sina Mirtorabi},
title = {{OSPFv2 Multi-Instance Extensions}},
pagetotal = 9,
year = 2012,
month = mar,
abstract = {OSPFv3 includes a mechanism to support multiple instances of the protocol running on the same interface. OSPFv2 can utilize such a mechanism in order to support multiple routing domains on the same subnet. This document defines the OSPFv2 Instance ID to enable separate OSPFv2 protocol instances on the same interface. Unlike OSPFv3 where the Instance ID can be used for multiple purposes, such as putting the same interface in multiple areas, the OSPFv2 Instance ID is reserved for identifying protocol instances. This document updates RFC 2328. {[}STANDARDS-TRACK{]}},
}
@misc{rfc5709,
series = {Request for Comments},
number = 5709,
howpublished = {RFC 5709},
publisher = {RFC Editor},
doi = {10.17487/RFC5709},
url = {https://www.rfc-editor.org/info/rfc5709},
author = {M Fanto and Randall Atkinson and Michael Barnes and Vishwas Manral and Russ White and Tony Li and Manav Bhatia},
title = {{OSPFv2 HMAC-SHA Cryptographic Authentication}},
pagetotal = 14,
year = 2009,
month = oct,
abstract = {This document describes how the National Institute of Standards and Technology (NIST) Secure Hash Standard family of algorithms can be used with OSPF version 2's built-in, cryptographic authentication mechanism. This updates, but does not supercede, the cryptographic authentication mechanism specified in RFC 2328. {[}STANDARDS-TRACK{]}},
}
@misc{rfc5340,
series = {Request for Comments},
number = 5340,
@ -138,6 +183,38 @@
howpublished={Available at \url{https://grafana.com/grafana/}},
note={Accessed: 2023-07-17}
}
@misc{python,
url={https://www.python.org/},
urldate={2023-07-20},
author={Python Software Foundation},
title={Python},
howpublished={Available at \url{https://www.python.org/}},
note={Accessed: 2023-07-20}
}
@misc{qt6,
url={https://www.qt.io/product/qt6},
urldate={2023-07-20},
author={The Qt Company},
title={{Qt} 6},
howpublished={Available at \url{https://www.qt.io/product/qt6}},
note={Accessed: 2023-07-20}
}
@misc{graphviz,
url={https://graphviz.org/},
urldate={2023-07-20},
author={The Graphviz Authors},
title={Graphviz},
howpublished={Available at \url{https://graphviz.org/}},
note={Accessed: 2023-07-20}
}
@misc{czelanet,
url={https://www.czela.net/},
urldate={2023-07-20},
author={czela.net z.s.},
title={{czela.net}: Metropolitní síť v {Č}elákovicích a okolí},
howpublished={Available at \url{https://www.czela.net/}},
note={Accessed: 2023-07-20}
}
@misc{cacti,
url={https://www.cacti.net/},
urldate={2023-07-17},

@ -9,11 +9,11 @@ this we derive a set of properties Birdvisu should fulfil.
\section{Existing approaches to network monitoring}
Several approaches to network monitoring and status visalisation already exist.
Several approaches to network monitoring and status visualisation already exist.
These can be approximately split into several types: visualisation of existing
data, traffic visualisation, host monitoring systems and integrated system
management platforms. Here we introduce them shortly and explain their
potential disadvantages, compared to visualisation of routing data.
potential disadvantages, compared to visualisation of routing information.
\subsection{Visualisation of existing data}
@ -21,8 +21,8 @@ Tools in this category do not collect any data on their own, rather only
focusing on visualising data from other tools. These projects are often small,
can be easy to run and allow visualisation of various data, but they require
other infrastructure to provide the data. For example, the Network
Weathermap\cite{weathermap} project can be used to provide overview based on
data in Cacti or other tools. Grafana\cite{grafana} provides many different
Weathermap~\cite{weathermap} project can be used to provide overview based on
data in Cacti or other tools. Grafana~\cite{grafana} provides many different
methods of visualising data from various databases.
This does not seem to be usable for visualising OSPF state, because we are not
@ -38,18 +38,18 @@ the system state, as we will see in section~\ref{s:net-split}.
These projects usually store a time series of utilisation and therefore need to
be deployed on some central server as long-running services.
Examples of this approach include Cacti\cite{cacti} and Munin\cite{munin}.
Examples of this approach include Cacti~\cite{cacti} and Munin~\cite{munin}.
Although both mentioned projects can graph other data, plugins for data
collection are available, so this differentiates them from the previous group.
\subsection{Host monitoring systems}
Projects in tis category do not necessarily consider the whole network system,
Projects in this category do not necessarily consider the whole network system,
but check state of individual hosts. It is possible for them to run locally, as
is the case for Plotnetcfg\cite{plotnetcfg}, or check the host over the network
(CaLStats\cite{calstats}, Icinga\cite{icinga}), but they do not provide
is the case for Plotnetcfg~\cite{plotnetcfg}, or check the host over the network
(CaLStats~\cite{calstats}, Icinga~\cite{icinga}), but they do not provide
overall picture. The capabilities of these tools also differ, from just
checking reachability (CaLStats) to being able to retreive various details from
checking reachability (CaLStats) to being able to retrieve various details from
the hosts (Icinga, plotnetcfg).
This approach can also miss some issues with the system, as described in the
@ -60,19 +60,19 @@ section~\ref{s:net-split}.
Some network administrators have created platforms for managing the hosts
across the network system. These systems usually know various aspects of the
system and may provide features like configuration generation or topology
visualisation\cite{nodewatcher-paper}. However, many of these are tailored for
visualisation~\cite{nodewatcher-paper}. However, many of these are tailored for
the specific system and are therefore not reusable in other environments.
Also, since large number of people need to access such platforms, they are
usually server based with web interface\cite{nodewatcher-paper}.
usually server based with web interface~\cite{nodewatcher-paper}.
\subsection{Topolograph}
We are aware of the only project that would allow visualisation of OSPF
topology, Topolograph\cite{topolograph}. While it does not collect its own
data, its companion project, Ospfwatcher\cite{ospfwatcher}, is able to retrieve
current topology data from a Quagga\cite{quagga} routing daemon. The deployment
involves setting up Logstash\cite{logstash}, so this is only suitable to be run
We are aware of only one project that would allow visualisation of OSPF
topology, Topolograph~\cite{topolograph}. While it does not collect its own
data, its companion project, Ospfwatcher~\cite{ospfwatcher}, is able to retrieve
current topology data from a Quagga~\cite{quagga} routing daemon. The deployment
involves setting up Logstash~\cite{logstash}, so this is only suitable to be run
on a server.
Also, we find the interface of Topolograph impractical to use (tested in
@ -81,7 +81,7 @@ Firefox version 116.0b2).
\subsection{Summary of existing tools}
As we have seen, various projects are available, but they often have some
important disadvantage. Table~\ref{t:comparison1} summarizes available projects.
important disadvantages. Table~\ref{t:comparison1} summarizes known approaches.
\bgroup
\def\yes{\checkmark}
@ -110,7 +110,7 @@ important disadvantage. Table~\ref{t:comparison1} summarizes available projects.
Birdvisu aims to be a rather simple tool for small to medium-sized network
systems, where it is impractical to deploy complex monitoring and visualisation
infrastructure. We want to especially help in homelabs and community wireless
networks\X{glos}, but any OSPF deployment should be able to make use of our
networks, but any OSPF deployment should be able to make use of our
project.
Also, since we do not require any server apart from a routing daemon, which can
@ -118,7 +118,7 @@ be running on any laptop, Birdvisu might also be a helpful tool for admins in
the field trying to fix broken infrastructure.
The primary motivation for implementing Birdvisu was the need of the author,
who has a dynamically routed system that switches uplinks depending on which
who has a dynamically routed system that switches uplinks depending on which of them
currently work. % Pls don't tell the dorms :-)
\section{Goals of Birdvisu}

@ -1,7 +1,7 @@
\chapter{Analysis}\label{ch:analysis}
In order to avoid as many problems as possible when visualising and
analysing a OSPF topology, we need to understand several aspects of networking,
analysing an OSPF topology, we need to understand several aspects of networking,
the OSPF protocol and its implementation in BIRD. However, the aim of this
thesis is not to be a complete guide to OSPF nor BIRD, therefore, for the sake
of brevity, we skip many details which do not influence our project.
@ -13,9 +13,9 @@ BIRD routing daemon.
\section{OSPF overview}
OSPF\cite{rfc2328,rfc5340} is a link-state routing protocol, which means that routers try to understand
OSPF~\cite{rfc2328,rfc5340} is a link-state routing protocol, which means that routers try to understand
the whole topology of the network and find the best path using an algorithm for
finding the shortest paths. Usually, Dijkstra's algorithm \X{ref?} is used.
finding the shortest paths. Usually, Dijkstra's algorithm is used.
OSPF was designed to provide dynamic routing in an entire autonomous system, but
running it on a much smaller scale is also possible.
@ -25,7 +25,7 @@ contain information about which network segments are incident to which
router on which interfaces and with which routers it is possible to communicate
on those interfaces. To distinguish between routers, each router is assigned a
32-bit number called \emph{Router ID} by the network administrator.
Router IDs are usually written in a quad-dotted notation \X{glos}.
Router IDs are usually written in a quad-dotted notation.
The LSAs are flooded throughout the system in order to let all the routers know
about the current topology. To avoid overloading the system just with this
@ -43,7 +43,7 @@ The area 0.0.0.0 is called the \emph{backbone area} and all other areas must be
incident to it, so that it has all the routing information. When this is
impractical, OSPF allows two routers to be connected using a \emph{virtual
link}. From the routing perspective, this is a point-to-point connection
between the routers in the backbone area. which allows to forward LSAs through
between the routers in the backbone area, which allows to forward LSAs through
other areas even when these LSAs would not normally leave those areas.
There are several types of networks that emerge in OSPF topologies. The
@ -72,58 +72,58 @@ paths to routers and networks in that area, including the external, extra-area
and stub networks adjacent to that area. OSPF specifies that the graph has all
the networks and routers as vertices, directed edges lead from each router to the
incident network with the configured cost and from each transit network to
incident routers with cost 0 (except when the two-part metric\cite{rfc8042} is
incident routers with cost 0 (except when the two-part metric~\cite{rfc8042} is
implemented). There are no edges starting at the external, extra-area or stub
networks, so that the shortest path DAG calculation does not find paths
through them.
The cost of the edge to an external network can be of two types. Type 1 cost is
specified in the same units as the internal costs, Type 2 cost is larger than
any internal or type 1 cost.
The cost of the edge to an external network can be of two types. A type~1 cost
uses the same units as the internal costs, whereas any type~2 cost is larger than
all internal or type~1 costs.
The OSPF family of routing protocols has undergone long evolution since the
first specification in 1989\cite{rfc1131}, There are currently two versions of
first specification in 1989~\cite{rfc1131}. There are currently two versions of
the protocol in use -- versions 2 and 3. While the basic idea is still the
same, OSPFv2 can only handle IPv4 systems. Although OSPFv3 claims to be
network-protocol-independent, it is usually only used with IPv6 systems and in
network-protocol-independent, it is usually only used with IPv6 systems and, in
fact, features like virtual links can only be used with that network
protocol\cite{rfc5838}.
protocol~\cite{rfc5838}.
Both OSPF versions have numerous extensions, as can be seen by the number of
RFCs that update the base specifications\cite{rfc2328,rfc5340}. Therefore, we
RFCs that update the base specifications~\cite{rfc2328,rfc5340}. Therefore, we
do not implement the protocol ourself, but rather find a suitable routing
daemon \X{glos} to determine the current topology.
daemon to determine the current topology for us.
Many improvements of the protocol only affect the topology construction (e.g.
NSSA areas\cite{rfc3101}) or change the data exchange between routers
(Multi-instance extensions\cite{rfc6549}, authentication\cite{rfc5709}, \dots).
NSSA areas~\cite{rfc3101}) or change the data exchange between routers
(multi-instance extensions~\cite{rfc6549}, authentication~\cite{rfc5709}, \dots).
By extracting the topology from a routing daemon, we can support many OSPF
extensions for free. For this reason, it is mostly sufficient to only consider
the base specifications of OSPF.
\section{Routing daemon selection}
While we were mostly determined to use BIRD\cite{bird} from the start, since we already
While we were mostly determined to use BIRD~\cite{bird} from the start, because we already
had some experience with it, let us present here a short summary of other
possibilities. Note that the particular choice does not affect interoperability
with other routers as long as the chosen routing daemon supports extensions
used in the network system.
There are several implementations of both versions of the OSPF protocol.
However, many of them are tied to the specific router hardware, which makes it
impractical to connect to a graphical visualisation. Moreover, even evaulating
However, many of them are tied to the specific router hardware, which makes them
impractical to connect to a graphical visualisation. Moreover, even evaluating
the feasibility would require us to obtain the specific hardware. Therefore, we
only consider hardware-independent solutions.
While we are aware of several software implementations, many of these do not
seem to be developed anymore (Quagga\cite{quagga}, XORP\cite{xorp},
OpenOSPFd\cite{openospfd}). Apart from BIRD, we only found FRRouting\cite{frr}
to be maintained, meaning that it had a release in the past year. While being
seem to be developed anymore (Quagga~\cite{quagga}, XORP~\cite{xorp},
OpenOSPFd~\cite{openospfd}). Apart from BIRD, we only found FRRouting~\cite{frr}
to be maintained, meaning that a new version has been released in the past year. While being
maintained is not a strict requirement, it would allow us to use that
implementation in case OSPF is extended again.
However, even BIRD does not implement all the extensions, for example, the
two-part metric\cite{rfc8042}.
two-part metric~\cite{rfc8042}.
\section{BIRD interface}
@ -132,15 +132,15 @@ line-based protocol slightly resembling SMTP. The client may send
commands to the daemon, which provides responses. The response may be long and
possibly formatted into a table. This interface is primarily aimed at human
users, so a rather simple client, \texttt{birdc}, is provided in the BIRD's
package\X{glos?}.
package.
While there is a note of a machine-readable protocol in the
\texttt{doc/roadmap.md} file in BIRD's source code\cite{bird-src}, it is not
\texttt{doc/roadmap.md} file in BIRD's source code~\cite{bird-src}, it has not been
implemented, so we will need to interface using the socket. This has following
consequences, most of which are not very pleasant:
\begin{itemize}
\item The responses to different formats often have completely different
\item The responses to different commands often have completely different
formats. This necessitates creating a dedicated parsing routines for each kind
of command we want to use.
\item There is no guarantee that the output will not change between versions.
@ -156,20 +156,20 @@ BIRD provides only a few commands that deal with OSPF:
\begin{itemize}
\item \texttt{show ospf} shows a simple summary of the running instances of
OSPF, like which areas are they in or how many LSAs does BIRD currently
OSPF, like which areas are they incident to or how many LSAs does BIRD currently
consider.
\item \texttt{show ospf interface} describes a current status of the individual
\item \texttt{show ospf interface} describes the current status of the individual
local interfaces: their configuration, designated routers for the incident
network, etc.
\item \texttt{show ospf neighbors} provides details about the state of
communication with adjacent routers.
\item \texttt{show ospf lsadb} returns details about known LSAs. Unfortunately,
communication with neighbour routers.
\item \texttt{show ospf lsadb} returns the details about known LSAs. Unfortunately,
this contains low-level information like checksums and sequence numbers,
but not details about networks or routers.
\item \texttt{show ospf state} shows an overal view of the ospf graph
\item \texttt{show ospf state} shows an overall view of the OSPF graph
representation: present routers and networks, costs of links, distances, \dots
\item \texttt{show ospf topology} seems to only provide a subset of the output
of \texttt{show ospf state}. For example, it does not provide info about
of \texttt{show ospf state}. For example, it does not provide information about
any non-transit networks.
\end{itemize}
@ -184,14 +184,14 @@ Let us look in depth at the \texttt{show ospf state} command, since we will be
using it and the format of its output a lot.
The command has two optional parameters. First, the flag \texttt{all} may be
added to show details not only the reachable part of the system, but from all
added to show details not only about the reachable part of the system, but from all
the known and non-expired LSAs. The difference between the topologies can be
used to discover network problems even without configuring the expected state.
The second parameter is a name of the OSPF instance. It is only required when
BIRD is running multiple instances simultaneously. This is unfortunately quite
common, because in dual-stack\X{glos} systems there needs to be a separate
instance of OSPF configured for each IP version.
common, because in dual-stack systems there need to be two separate
instances of OSPF, each configured for different IP version.
The output of the command is a tree of lines representing the topology itself.
Children of a directive are indented by one more tab. An example output is
@ -222,8 +222,8 @@ area 0.0.0.1
The tree as output by BIRD\footnote{The format was determined by
experimentation and inspecting of \texttt{proto/ospf/ospf.c} in BIRD's source
code\cite{bird-src}.} has three levels, we call them top-level, level-2
and level-3. The top level only contains directives of form \texttt{area
code~\cite{bird-src}.} has three levels, we call them top-level, level-2
and level-3. The top level only contains directives of the form \texttt{area
AreaID}, with the AreaID being written in the quad-dotted notation.
On level-2 are mentioned all the routers and networks in the area. This is
@ -240,7 +240,7 @@ There is also a level-3 line for each incident host and network. Overview of
the \uv{tags} (the first words) and parameters is provided by
table~\ref{tab:ospf-incidences}. Note that networks can only be incident to
routers, while routers may be incident to anything. The incidences of routers
have also a metric, after the word \texttt{metric}, or, in case of Type 2
have also a metric, after the word \texttt{metric}, or, in case of type 2
external cost, \texttt{metric2}.
\begin{table}[h]
@ -278,16 +278,16 @@ incidence line for object B in a level-2 block of object A, there exists an
edge from A to B in the topology used by the Dijkstra's algorithm. This fact
will later simplify parsing.
\section{Test network system: Gennet}
\section{Test network system: Gennet}\label{s:gennet}
To help test Birdvisu and understand network behaviour, we created a simple set
of scripts called Gennet. Sice it was mainly written to aid Birdvisu, we
of scripts called Gennet. Since it was mainly written to aid Birdvisu, we
provide it as attachment~\ref{att:gennet} of this thesis.
Gennet is a network generator. Using a hard-coded configuration and a set of
Jinja2\cite{jinja2} templates, it provides a semi-automatic way of
Jinja2~\cite{jinja2} templates, it provides a semi-automatic way of
creating several virtual machines (their disk images and startup scripts) and
configuration to connect them using software bridges\X{term?}. This will allow
configuration to connect them using software bridges. This will allow
changing the state from the host operating system, simulating various network
conditions.
@ -295,7 +295,7 @@ We fully admit that Gennet is really just a quick hack. However, since it was
created specifically to aid the development of Birdvisu and because it provides
a reproducible environment, we think it makes sense to attach it to this thesis. The
particular choice of technologies (Jinja2, Python, Bash, QEMU and Alpine
Linux)\X{refs!} is driven solely by our previous experience with them and
Linux) is driven solely by our previous experience with them and
should not affect the behaviour of the generated system in any way.
%Gennet is used as follows: the user must first generate a base Linux image,
@ -351,7 +351,7 @@ We focus on behaviour of BIRD in following scenarios:
\item Network split: Hosts in the same network stop being able to
communicate with some other host in the same network. This is often
caused by a broken cable or switch malfunction.
\item Multiple links to same networks: It might make sense to connect a
\item Multiple links to the same network: It might make sense to connect a
single router to the same network using multiple links, possibly with
different costs. This provides redundancy and helps e.g. avoid network
splits.
@ -368,8 +368,8 @@ depending on the version of OSPF.
Network splits are of particular interest to administrators. Not only are they
symptoms of a broken part of the infrastructure, but also every netsplit
inherently means that some addresses from the split network can not be reached
by some hosts, because there is no hint, to which segment a packet
should be delivered.
by some hosts, because there is no hint which segment a packet
should be delivered to.
Splits can also be tricky to spot from systems using topology-unaware approaches,
because if a link connecting two switches fails, all ports on hosts are still
@ -444,7 +444,7 @@ very creative, there are some limits to such creativity.
The largest system which can be spanned by a single OSPF instance is the whole
autonomous system (AS). The largest ASes only have about several hundred
thousand routers\cite{as-topologies}. The average degree also seems to be rather
thousand routers~\cite{as-topologies}. The average degree also seems to be rather
low.
We can derive another limit from IPv4 address allocations. A /8 block (i.e.

@ -4,12 +4,12 @@ We now explain the design of Birdvisu in depth. First, we explain some
important decisions and present the overall structure of the project, then we
look into individual parts of the program.
Birdvisu is implemented in Python, using PySide6, the official bindings for
Qt6, for drawing on screen. We decided to use Qt, because it provides a lot of
Birdvisu is implemented in Python~\cite{python}, using PySide6, the official bindings for
Qt6~\cite{qt6}, for drawing on screen. We decided to use Qt, because it provides a lot of
pre-made widgets and tools and since it is widely used, it is easy to find help
for it on the Internet. The decision to use Python was not hard either. Not
only Qt has official bindings for it, but we use the language very often and
thus are comfortable writing in it. We do not expect the potential slowness of
thus are comfortable writing software in it. We do not expect the potential slowness of
Python to be an issue, because for handling graphics we are using Qt, which is
written in C++. Also, as we have analysed in section~\ref{s:areas}, we expect
the topologies to be quite small.
@ -24,21 +24,391 @@ topology on the screen, highlighting the relevant information.
\section{Recurring and general patterns}
\XXX{dictionaries everywhere, hashable recipes. ospffile with comments as a reusable format. Format of VertexID}
Birdvisu's data structures make heavy use of dictionaries and sets, because we
do not handle much data that would need to be processed in any particular
order. While this allows us to perform set operations quickly, it requires us
to provide hashable keys.
We have decided to embrace this requirement and use rather complex frozen
dataclasses, which can hold as much of the required data as possible, as long
as we can re-create that data.
This can be illustrated on our usage of vertices in topology. There are two
objects: a VertexID, and the Vertex itself. VertexID is the hashable part and
Vertex provides additional information, like incident edges, which are not
hashable. The topology then has a dictionary from the VertexIDs to Vertices,
providing the complete data.
However, the VertexID already contains information like what version of IP it
belongs in, whether it represents a router and all the possible IP addresses
and identifiers related to the vertex. It is sufficient for Vertex objects to
only contain sets of edges and references to the related topology and VertexID.
(In the next section, we will see that a type of the vertex is also stored in
Vertex, but that is really everything.)
The other thing we decided to reuse was the format of BIRD's topology output.
We call the format \uv{ospffile} and have extended it by allowing comments (after an
octothorpe, i.e. \verb|#|). Also, empty lines do not seem to be of relevance.
These are quality-of-life improvements for cases when ospffiles are edited by
hand.
\clubpenalty=1000
Apart from storing topologies, we intend to use ospffiles for description of
basic styles. Therefore, our implementation in \verb|birdvisu.ospffile| only
constructs the tree of strings and does not try to understand it. Our module
provides API similar to the one of \verb|json| or \verb|marshall| modules, even
though it cannot represent arbitrary types.
\section{Data collection: providers and parsing}
\XXX{sub-parts, why a topology is not a graph, stacking topologies with
multiedges, fake-freezing, why is everything static. Graph representation, selection of BIRD's
instance}
This part of the project deals with processing topologies. The core object of
this part is a TopologyV3\footnote{The \uv{V3} suffix is sometimes impractical
to keep, so we will sometimes shorten the class name only to \uv{Topology}. It
denotes the same object.}. While the Topologies can be created manually by
adding the vertices and edges, we expect that retrieving topologies from other
sources like saved ospffiles or running BIRD processes. This is made possible
by implementing a TopologyProvider.
Representing a topology turns out to be a bit complicated problem for the following reasons:
\begin{itemize}
\item The topology edges need to be directed. OSPF allows a shortest path
from A to B to be different to the other direction.
\item It can have a very general shape, so we cannot rely on common
patterns. For example, routers can be connected to other routers using
point-to-point or virtual links, not just networks.
\item The objects are shape-shifting. A transit network may become stub or
change the designated router and we want to be able to understand the
change as best as possible.
\item The topology is not necessarily a graph, because multiple links may
lead from a single router to the same network. However, we strongly
believe that the maximum number of parallel edges is quite low, so most
of the theory for simple graphs is still applicable.
\item For completeness, we note here again that the shortest paths from a
single vertex form a DAG, even though the OSPF specifications speak of
them as of trees. (Negative edges are, fortunately, not permitted.)
\end{itemize}
Given the above requirements and lessons learned in
section~\ref{s:net-unusual}, we need to find a representation of vertices, that
is both powerful enough to uniquely describe a particular vertex, and flexible
to allow us easily detect its metamorphoses. The table~\ref{tab:vertexid}
shows, which information we can use for each type of object. We see that
networks in particular are hard to represent, because the ID of the DR may
change and it might be the only distinguishing property in case of a split
network.
\bgroup
\def\yes{\checkmark}
\def\chg{$\bullet$}
\begin{table}[h]
\centering
\begin{tabular}{cccccc}\hline
Object & Address & RID & DR ID & IF ID & Notes \\\hline
\verb|router| & -- & \yes & -- & -- &\\
\verb|xrouter| & -- & \yes & -- & -- &\\
\verb|vlink| & -- & \yes & -- & -- & Peer is a \verb|router|\\
\verb|network| & v2:\yes,v3:$*$ & -- & \chg & v3:\chg &\\
\verb|external| & \yes & -- & -- & -- &\\
\verb|xnetwork| & \yes & -- & -- & -- &\\
\verb|stubnet| & \yes & \yes & -- & -- &\\
\end{tabular}
\caption{Information determining each object of a topology. $*$ means it
may or may not be known, \chg\ denotes an attribute that may change. Columns in
order: whether it has assigned a address, relevant router ID, ID of designated router, interface number of the DR.}
\label{tab:vertexid}
\end{table}
\egroup
We decided to aim for correctness, so whenever any of the attributes of an object
change, we consider it to be a a separate object. This may create some false
positives, but we think that is the better case than potential false negatives,
which could hide some issues. Also, when the infrastructure works correctly,
the designated router should only change in case of outage. Therefore, it might
actually be useful to notice the user when a network has an unexpected
designated router even when it is otherwise healthy. However, we provide a way
to find objects by partial information, using the VertexFinder objects, so this
allows heuristics to match different objects.
The information mentioned in table~\ref{tab:vertexid} serves as the main part
of the VertexID. However, we want the VertexID to identify the same object even
after it transforms to another kind of object, so instead of using the object
type, we only note whether the object is a router or a network, since this
property stays the same even for changed objects. The code is also oblivious to
the fact that the interface ID is a number and what it means -- we use it as an
opaque \uv{discriminator} and do not even bother with parsing it from a string.
The VertexIDs are supposed to be descriptors of objective vertex state, so they
do not belong to any particular TopologyV3. Instead, they can be used to track
actual Vertices across multiple Topologies.
Apart from VertexIDs, the TopologyV3 also consists of the additional data in
Vertex objects and Edges. The Vertex objects, as noted above, contain only a
set of incoming and outgoing edges, references to their TopologyV3 and VertexID
objects and the actual type of the object the vertex represents (i.e.\ the first
column of the table).
An Edge knows the source and target VertexID, its cost and the number of
parallel edges with these properties. If the Edge was determined by a virtual
link, it is marked as virtual. This is needed, because the both Vertices are
regular routers, so the information about the virtual link cannot be stored in
them. Note that an Edge does not need to belong to any Topology, since it only
contains factual data. The information, whether an Edge is in the topology, is
stored only in the incident Vertices.
A Topology can be marked as \uv{frozen}. This denotes an intent that it really
should not be modified, because other code might rely on the particular shape
of the Topology. However, making the Topology truly immutable would be
impractical in Python, so we opted for this approach. In case our solution
turns out to be prone to accidental modification of the Topology, we will
deploy additional countermeasures against that.
Frozen Topologies also allow us to stack them, creating a union of the original
Topologies. This way, a single Topology can be used in the visualisation, while
keeping the original information. This mechanism is fully generic, but was
mainly invented to allow merging the reference (expected) topology with the
actual one (i.e.\ the current state of the system). The ancestors are stored by
a string label in a dictionary of the Topology. While subclassing TopologyV3
into a StackedTopology would probably be a cleaner design, since the only
difference is a state of one dictionary, we did not employ this approach.
The TopologyProviders are not very interesting, but are important nevertheless.
There are a few caveats with parsing topologies from the ospffile format.
First, the edges from routers to networks can only be resolved after the
networks are known, since network's level-2 block contains information not
present in the level-3 directive for the router (namely, the designated router
for OSPFv2 networks and the set of addresses for OSPFv3).
Since BIRD may be running more than one instance of OSPF, the
BirdSocketTopologyProvider contains an ad-hoc parser of the response to the
\texttt{show protocols} command, which seems to be a reliable way to list
running instances.
Moreover, BIRD does not seem to expose any way to determine the version of
OSPF. So far, we think it is sufficient to guess from the \texttt{network}
directives, since they seem to contain a hyphen if and only if the dump is from
an OSPFv3 instance. (The source code of BIRD suggests that under some
circumstances, brackets can appear even in OSPFv2 dump, so that is not a
possibility.)
\section{Annotations}
\XXX{scoping, annotator creation, advantages of storing data in annotations and
not vertices. Annotator protocol and posibility of export. Various uses of annotators: enhancing, analysis, visualisation}
Once a TopologyV3 is obtained, it may be annotated. An Annotator may create an
Annotation, which is then stored as a part of an AnnotatedTopology. We now
explore design of these objects in detail.
An Annotation is essentially only a holder for any \uv{tags} that are to be
attached to the topology. These are represented by a dictionary holding
annotations for Vertices, another dictionary for annotating Edges, and a single
field allowing the attachment of a tag to the entire Topology. The keys of the
dictionaries are VertexIDs and Edges, respectively.
The Annotation can only attach one tag to each vertex and edge, but there are
little restrictions of what the tag is allowed to be. The intention is to allow
Annotators to provide any useful data they can collect. However, we think that
our AnnotatedTopologies could be utilised in other projects, so the Annotation
objects ought to be easy to serialise into JSON or other formats.
Annotations do not need to take other Annotations into account, because
AnnotatedTopology stores Annotations from different Annotators separately.
The Annotators are a tiny bit more interesting. While these objects are
basically wrappers around the \verb|annotate()| method, which takes an
AnnotatedTopology and returns an Annotation, there are few twists to it.
First, an Annotator object is intended to be created by the respective
AnnotatedTopology in order for it to keep track of all the Annotators. To
describe an Annotator, an AnnotatorID is used, which is a re-creatable and
hashable recipe for creating that Annotator. It is also used as a handle to
reference and scope the resulting Annotation. The AnnotatorID is a pair of the
type object of the particular Annotator, and an optional hashable parameter,
which is passed to the Annotator's initialiser.
Second, an Annotator might require another Annotator to have already run. We
make this possible by allowing Annotators to request another Annotator to be
run by the AnnotatedTopology (provided the AnnotatorID), as long as there is
not a dependency cycle. This is the recommended method of implementing
dependencies of Annotators.
Furthermore, an Annotator can be declared to be idempotent. This affects what
happens when the same Annotator is invoked on the same Topology in the same way
(that is, using the same AnnotatorID) multiple times. For idempotent
Annotators, we know that their output will not change, so the Annotator is not
really run. For non-idempotent Annotators, the previous Annotation is removed
and the Annotator is run again.
Annotators may not alter the AnnotatedTopology in any way. They are only
allowed to return an Annotation, which will be added to the AnnotatedTopology.
As with frozen Topologies, this is not enforced by the code.
Annotators may be used for various tasks, including but not limited to
performing analysis of the Topology, enhancing it with additional data (e.g.
ping response times from other system), or specifying parameters for
visualisation. As a part of Birdvisu itself, we ship several annotators:
TopologyDifference outputs the differences between the reference and current
Topology, and ShortestPathTree marks the edges of the shortest path DAG. The
next section describes how Annotators aid visualising the data.
The last important object related to annotation is the AnnotatedTopology. It
serves as a coordinator for running Annotators. It does two main things:
detects dependency cycles between Annotators, and keeps the Annotations.
The Annotations in the AnnotatedTopology are stored in a dictionary indexed by
the respective AnnotatorID. For vertices and edges, only sets of AnnotatorIDs
are stored. This way, both iterating Annotations for a Vertex or Edge and
examining individual Annotations is fast. Also, our approach isolates unrelated
Annotations by putting them into different scopes by AnnotatorID.
However, by using the Annotator's type in AnnotatorID, this design enforces a
rather tight coupling between Annotators and users of Annotations, because the
consumers of Annotations need to understand the precise format of the
particular Annotation. This could be solved by implementing support for
\uv{interface-annotators}, so that various Annotators may provide Annotations
in a commonly understood format.\footnote{Preliminary work on implementing this
approach is present in the \texttt{ann\_interfaces} branch, but the interaction of
implementers of the same interface is not decided yet.}
AnnotatedTopology does not expose a way to delete old Annotations. While we do
not expect this to cause big memory leaks, in case it does, an LRU-like
strategy might be employed to tame the memory usage. Also, the Annotators could
be run dynamically when the Annotation is requested, but our current approach
does not need this functionality, so it is not implemented at the moment.
\newpage
\section{Visualisation}
\XXX{Layouting (nonexistent), why not graphviz, why not consensual metrics, how we are re-using annotations internally. Saving layouts}
The visualisation is split into two parts: computing the appearance and
actually showing the result. For the former we reuse the Annotator
infrastructure. The latter is handled by Qt's Graphics view framework.
\widowpenalty=10000
The appearance is described by a styling dictionary. For vertices, it contains
a position and a highlighting colour. Edges can have a colour, line width and a
highlighting colour. However, more styling properties can be defined in the
future.
To provide those styling dictionaries, a subclass of Annotators is created,
StyleAnnotator. StyleAnnotators only differ from regular Annotators in that
they only tag vertices and edges with styling dictionaries. This provides
something similar to an interface, helping to uncouple the style from the
specific Annotator that provided the respective data. Each Annotator which
provides data worth showing has a companion StyleAnnotator to provide the
respective style. When drawing, we pick one StyleAnnotator and highlight the graph
according to it.
The current approach avoids mixing styles from multiple Annotators, which might
be required for more advanced use in the future. We considered using
stylesheets similar to CSS, but we think that approach is too heavy-weight.
Rather, assigning priorities to the StyleAnnotators could allow a flexible
order of applying styles, but at this point this also seems like a unnecessary
complication of the project.
We let the user decide, where the vertices should be placed, because they might
have some idea or understanding of the system that is not present in the
topology. For this reason, we also ignore classical metrics of graph drawing,
like the crossing number of the layout. This can be demonstrated on the default
Gennet topology: while it forms a planar graph, it makes more sense to let the
edges cross as on figure~\ref{fig:gennet}, because the layered structure is
more important.
To store the placement, we reuse the ospffile format. An example is shown in
listing~\ref{lst:visufile}. The top-level contains a \verb|visualisation|
directive, so that other information may be stored in the same file in the
future. Level-2 contains vertex specification in the same format as in dumps
from BIRD. On level-3 there is a \verb|position| directive with the
coordinates, but for transit networks, additional details (DR or address) can
be provided to specify the correct network. Similarly, we allow a \verb|router|
level-3 directive to be used in the \verb|stubnet| block. This format allows
using BIRD's output as the basis for the placement file and could be extended
by other directives if needed in the future.
\begin{lstlisting}[float=h,label=lst:visufile,caption=Vertex placement description]
visualisation
router 192.0.2.14
position 200 200
network 192.0.2.0/28
position 0 1500
dr 192.0.2.14
\end{lstlisting}
We try to place vertices without known position in proximity to already placed
neighbours, so that the user can easily locate them. Since the neighbours can
also have unknown position, BFS is used: we place the vertices of known
positions, then their neighbours in their proximity, then the neighbours'
neighbours and so on. When there is a completely unplaced component, we place
one of its vertices at random. However, disconnected topologies are of little
interest to us.
We tried using Graphviz~\cite{graphviz} for laying out the vertices, but we
were not satisfied with its result. To demonstrate, the
listing~\ref{lst:graphviz} describes the topology of our home network with
Gennet attached. Figure~\ref{fig:graphviz} then shows how each of Graphviz's
layout engines draws the topology. While it could be possible to tweak the
engine settings, we believe the user still knows better, so we did not continue
exploring this idea.
\lstinputlisting[float=h,label=lst:graphviz,caption=Author's home topology]{../img/graphviz-fail/source.dot}
\begin{figure}[h]
\centering
\begin{subfigure}[b]{0.8\textwidth}
\centering
\includegraphics[width=\textwidth]{../img/graphviz-fail/dot.pdf}
\caption*{dot}
\end{subfigure}
\begin{subfigure}[b]{0.8\textwidth}
\centering
\includegraphics[width=\textwidth]{../img/graphviz-fail/circo.pdf}
\caption*{circo}
\end{subfigure}
\begin{subfigure}[b]{0.45\textwidth}
\centering
\includegraphics[height=\textwidth,width=9cm,keepaspectratio,angle=90]{../img/graphviz-fail/sfdp.pdf}
\caption*{sfdp (rotated for clarity)}
\end{subfigure}
\begin{subfigure}[b]{0.45\textwidth}
\centering
\includegraphics[width=\textwidth]{../img/graphviz-fail/neato.pdf}
\caption*{neato}
\end{subfigure}
\begin{subfigure}[b]{0.45\textwidth}
\centering
\includegraphics[width=\textwidth]{../img/graphviz-fail/fdp.pdf}
\caption*{fdp}
\end{subfigure}
\begin{subfigure}[b]{0.45\textwidth}
\centering
\includegraphics[width=\textwidth]{../img/graphviz-fail/twopi.pdf}
\caption*{twopi}
\end{subfigure}
\caption{The unpleasant results of Graphviz's layout engines}
\label{fig:graphviz}
\end{figure}
In order to display the topology, we convert it to a simple undirected graph.
The set of vertices stays the same, the edges are only reduced to a pair of
VertexID without having any kind of cost associated with it. The only tricky
part is deciding the style of the new edge when the StyleAnnotator returned
multiple styles for the unified edge. We decided to pick the style of the
lightest positive-cost edge, since it is the most relevant in most cases:
zero-cost edges are almost always network-to-router edges\footnote{We are not
sure whether other zero-cost edges are permitted.} and heavier edges are not
used, because it is always cheaper to use the light edge. (We are aware that
this is not true for asymmetrically configured point-to-point links, but we do
not think they are commonly deployed.)
Since we want to be able to use edges in sets, we need a canonical hashable
representation. For that, we implement a total ordering on VertexIDs, which
allows us to use pairs of the VertexIDs in ascending order to reference the
edge. There are currently no specific requirements for the ordering to satisfy.
The vertices and edges of the simple graph have a one-to-one mapping to the
actual graphics items shown to the user. The Graphics view framework allows us
to create nested items, which we use for highlighting: a highlight is just a
bigger rectangle in a lower layer than the displayed object. Moreover, the
framework has built-in support for dragging and right-clicking objects, which
simplifies creating the UI.
Currently, the MainWindow object acts as a coordinator of everything that needs
to happen, from loading topologies and annotating them to putting them on the
scene and allowing the user to interact with them.

@ -1 +1,70 @@
\chapter{Usage}\label{ch:usage}
% Maybe this is too much of a guide, but I think a section with the user's
% description should be present and there is not much other content to write
% here. Also, the UI is currently horrible, so it is worth having this
% somewhere, and since there is no documentation, here is the place probably.
In this chapter we describe the program from the user's point of view and
present its features.
\section{Running Birdvisu}
First, the user needs to obtain Birdvisu from somewhere. Either, the
attachment~\ref{att:birdvisu} can be extracted, or the project can be
downloaded from its repository at
\url{https://gitea.ledoian.cz/LEdoian/birdvisu}, which will also contain any
future improvements.
The only strict dependency of Birdvisu is Python3.10 or newer. While the project
depends on the PySide6 library for the user interface, it can be downloaded
as a wheel from PyPI. Of course, using a system-wide installation of
PySide6 is also possible.
Birdvisu can read the topology information from files, so it is not necessary
to have a BIRD running and configured if only showing static data is required.
We only support running the project on Linux. However, Birdvisu might be able
to run on other types of operating systems, since we have only used
cross-platform libraries.
There are several ways to start the program. The recommended method is to
install the project into a Python virtual environment and using the \verb|visu|
command. Running the \verb|visu.py| script also works when PySide6 is installed
in the system, without requiring the installation step.
Once the program is started, the user is presented with an empty canvas. Using
the \emph{Topology} menu, it is possible to load both a reference and current
topologies. Both can be loaded from a file, the current one can also be
retrieved directly from a running BIRD via its socket. In the latter case, the
user is provided with a dialog to pick an area and OSPF instance.
Once both topologies are loaded, the graph of the topology appears. Now, the
vertices can be moved around to the user's liking. Alternatively, the
\emph{Positions} menu provides a way to load the positions of vertices from a file.
The program expects the topology files to have the \verb|.ospf| extension,
positioning files may end in \verb|.visu|. Nevertheless, any files may be used,
they just are not offered by default.
Several highlighting ways are available. In the \emph{Highlight} menu, the user
can choose to show differences between the reference and current topology, or
set the widths of edges according to their costs. Alternatively, by
right-clicking any vertex, it is possible to highlight its shortest path DAG.
If the user wants to find a specific route, showing the DAG also serves as
selecting the start vertex. The context menus for vertices then allow finding
the path to those vertices. Note that stub and external networks are sinks in
the OSPF topology, so it is expected that the program draws an empty DAG for them.
Finally, there is an option to reload the shown graph in the Topology menu. We
decided that the graph should not change unexpectedly, because that could be
unpleasant to use.
As a part of Birdvisu we ship the files \verb|gennet.ospf|,
\verb|gennet-changed.ospf| and \verb|gennet.visu| for demonstration purposes.
These files provide a topology of the default Gennet, the same topology with
several manual changes, and a placement of vertices like in figure~\ref{fig:gennet}.
\iffalse
\section{Extending Birdvisu}
\fi

@ -1 +1,88 @@
\chapter{Evaluation}\label{ch:evaluation}
To show that Birdvisu is a usable project, we have tried to use it in several
network systems, both synthetic and already deployed. Here we summarise our
experience with using it.
Because our project is mainly an interactive program, we do not present any
performance or other measurements. Therefore, we rather focus on the subjective
feeling of the project and evaluate the design decision from chapter~\ref{ch:design}.
\section{Gennet}
Naturally, Gennet, as described in section~\ref{s:gennet} is supported quite
well. Since we had complete control of the whole network, we could test e.g.
multi-area OSPF deployment, which is not common in real network systems, as far
as we are aware.
However, only small networks can be simulated in Gennet, because each router
requires disk and memory, which may be quite scarce.
\section{Our home network}
At home, the author relies on a dynamic routing to switch between falling
uplinks and to provide a simple way to address virtual machines across the
network system. This was one of the reasons we decided to look for
visualisations of OSPF topology state.
Since it only spans a single room, this system is even smaller than Gennet,
containing only three routers and less than 10 networks (the exact number
depends on which devices are up at the time). We believe that major issues do
not show up at this scale.
Naturally, Gennet can be connected to the home network. At that point, our
approach to laying out vertices starts feeling suboptimal, because edges cross
unnecessarily often. The connections are clear, however, and this can be
alleviated by using a fixed layout in a file. In the future, this could be
addressed by using a force-based approach for the automatic layout.
\section{Department of Applied Mathematics}
The department which advised this thesis also uses OSPF in its infrastructure.
Again, the main purpose is to address containers and virtual machines in the
system. The topology consists of 5 routers and about 27 networks, most of which
are stub.
As in the previous case, the main issue is the automatic vertex layout. Also, since most of the
networks are stub (and often only contain a single host), the graph could
position these networks near each other, or even collapse them into one vertex.
Birdvisu does not unfortunately support this at the moment.
\section{Czela.net}
Czela.net~\cite{czelanet} is a network system run by a community of network
enthusiasts in Čelákovice and the surrounding area. There are about 1600 people
connected to Czela.net. This is the typical OSPF
deployment, whose main task is to dynamically provide fallbacks in case of
outages. It is also an example of a larger network, with 45 routers, 32 transit
networks and 178 external routes\footnote{Most of these would be stub routes in
other deployments, but there is little difference from the topology perspective.}.
Unfortunately, their infrastructure does not use BIRD anywhere and we were not
able to connect our instance to any of their transit networks. Therefore we
only tested displaying the topology based on a dump from one of their MikroTik
routers, which we manually converted to mimic BIRD's format. We believe this
should not affect the performance much, because the retrieval of data from BIRD
is only occasional and once BIRD dumps the topology, the procedure is the same
as with loading the topology from file.
This turned out to be helpful for both us and Czela.net. We discovered that our
method of highlighting of costs does not work well with too big range of the
costs, and on the other hand, we found several misconfigurations in their
network (some routers had external routes to transit networks, a few networks
with routing-unaware clients were used as transit), even without any other
knowledge of their system.
We did not notice any performance issues when dealing with the topology.
\bigskip
Unfortunately, we did not have the opportunity to test in a large network (the
Czela.net's one is the largest we tested), so we do not really know the limits
of Birdvisu. Those are even hard to guess, because while we are trying to
use rather fast algorithms, they are implemented in Python, which can sometimes
be quite slow, and more importantly, does not support threads well. The heavy
use of hash tables and indirection can also impair performance.
Overall, the testing did not discover any important problems with the design of
Birdvisu, we are only aware of issues related to small parts of the project.

@ -1,2 +1,57 @@
\chapter*{Conclusion}
\addcontentsline{toc}{chapter}{Conclusion}
% Hacked figure number?
\setcounter{chapter}{6}
We developed a simple and standalone tool for visualising OSPF topologies. The
program is functional and can visualise network systems of medium size. The
project's design will allow additional features to be added in the future.
The project also meets the goals stated in chapter~\ref{ch:motivation}:
\begin{itemize}
\item Birdvisu utilises BIRD to collect data about the whole network system from a single host,
\item the project can be easily run from any Linux machine, not requiring any server-based setup, and
\item its topology-centric approach has successfully discovered minor issues with an existing OSPF deployment.
\end{itemize}
The only stated goal Birdvisu fails to fulfil at this time is the ability to
exchange data with other projects. However, the project's design expects such
functionality, so enhancing Birdvisu in this way should be easy in the future.
\bgroup
\def\yes{\checkmark}
\def\no{\texttimes}
\def\maybe{?}
\begin{table}[h]
\centering
\begin{tabular}{lccccc}\hline
Approach & CD & RS & CoH & EoD & T \\\hline
Only visualisation & \no & \maybe & \no & \maybe & \no \\
Traffic visualisation & \yes & \yes & \yes & \no & \no \\
Host monitoring & \yes & \maybe & \yes & \maybe & \no \\
Integrated management & \yes & \yes & \maybe & \no & \yes \\
Topolograph + Ospfwatcher & \yes & \yes & \no & \no & \yes \\\hline
\textit{Birdvisu} & \yes & \no & \no & \yes & \yes \\
\hline\end{tabular}
\caption{Comparison of Birdvisu's approach compared to other known approaches. See also table~\ref{t:comparison1}.}
\label{t:comparison2}
\end{table}
\egroup
\section*{Future work}
\addcontentsline{toc}{section}{Future work}
There are many ways Birdvisu can be expanded in the future. Apart from the
stated ones (exports, better vertex placements, \dots), it could be possible to
support other routing daemons and even other link-state protocols like Babel.
Another interesting possible use case could be running Birdvisu headless. When
combined with the export feature, this could allow using the project as a data
source for other visualisation tools. While this is currently not possible,
because the GUI controls all the parts of the program, it might be possible to
separate the GUI and the coordination part.
More Annotators could also be written to provide other functions, like
detecting single points of failure. And last, but not least, the user interface
can definitely be prettier.

@ -1,4 +1,31 @@
\chapter*{Glossary}\label{ch:glossary}
\addcontentsline{toc}{chapter}{Glossary}
\XXX{TODO}
% This is hard to format reasonably, so we at least try to do it consistently.
\strut\indent{}A \emph{bridge} is a networking device, which forwards link-level
frames between interfaces.
The term \emph{community wireless network}
describes a system of often wireless networks, which is managed by a community
rather than by an ISP.
\emph{Dual-stack} networks can forward and process both IPv4 and IPv6 packets.
When a program is run without being able to display graphical elements, it is said to be run \emph{headless}.
A \emph{homelab} is a small infrastructure, on which a network enthusiast can experiment and thus improve their networking skills.
\emph{Netsplit} is just a short form for \uv{network split}.
A \emph{next hop} is the name for the following router a packet is forwarded to.
In Linux distributions, a \emph{package} is a common way to distribute software.
\emph{Quad-dotted notation} denotes writing a
32-bit number as four decimal numbers representing individual bytes, with dots
between them. The numbers are written in the network order, also known as big-endian.
A \emph{routing daemon} is a program running on a router that exchanges routing information with other routers.
Python's current way of distributing compiled software is called \emph{wheel}.

@ -51,8 +51,8 @@
\lstset{basicstyle=\ttfamily\footnotesize,captionpos=b,columns=fullflexible,numbers=left,numberstyle=\color{gray}\footnotesize}
\def\X#1{\textcolor{red}{[#1]}}
\def\XXX#1{\par\smallskip\noindent \textcolor{red}{[#1]}}
%\def\X#1{\textcolor{red}{[#1]}}
%\def\XXX#1{\par\smallskip\noindent \textcolor{red}{[#1]}}
%%% Basic information on the thesis
@ -86,17 +86,29 @@
% An optional dedication: you can thank whomever you wish (your supervisor,
% consultant, a person who lent the software, etc.)
\def\Dedication{%
Dedication.
First, I would like to thank my supervisor Martin Mareš, for being hopeful and patient and for teaching me many useful skills.
For similar reasons, I am grateful for all the presentation and explanation skills the M\&M correspondence seminar has taught me.
This thesis would not also be done without my friends, colleagues and family for nudging and convincing me enough to finish my studies.
Last, but not least, I want to thank You, my dear reader, because right now You are making sure this thesis was worth writing.
}
% Abstract (recommended length around 80-200 words; this is not a copy of your thesis assignment!)
\def\Abstract{%
Abstract. \X{Recommended length around 80--200 words. This is not a~copy of your thesis assignment!}
Network administrators need to be aware of the state of their network. While
link-state routing protocols like OSPF have the required information, there was
no easy way to present it to the administrator. To solve this problem, we
developed Birdvisu, a program to visualise the topology as seen by the BIRD
Internet Routing Daemon. Our approach allows the topology to be easily
annotated with other data, providing an extensible way of analysing the
topology. While not fully featured yet, Birdvisu helped discover several
misconfigurations in a community-run network connecting about 1600 people.
}
% 3 to 5 keywords (recommended), each enclosed in curly braces
\def\Keywords{%
{key} {words} \X{usually 3 to~5 key words or phrases}
{OSPF}, {network visualisation}, {routing}, {BIRD}
}
%% The hyperref package for clickable links in PDF and also for storing

@ -36,18 +36,18 @@ shared network, and conversely, that two networks are neighbours when they
share a router.
We will use the word \emph{network system} (or just \emph{system}) to describe a
set of network managed by a single administrator, which is intended to forward
set of networks managed by a single administrator, which is intended to forward
packets across it. This can mean the whole autonomous system\footnote{This is
where we borrowed the word \uv{system} from.}, but often this is a much smaller
part. When we speak about routing using OSPF, a system is only the set of
networks that run a single instance of OSPF.
networks that run a single instance of the OSPF protocol.
By the term \emph{IP} we mean the Internet Protocol of either version 4 or 6.
When it is important to distinguish, we explicitly write \emph{IPv4} or
\emph{IPv6}. IP may also denote an IP address, as in \uv{a router has an IP},
but this usage should be clear from the context.
We distinguish between \emph{routing} as the act of finding next hops\X{glos},
We distinguish between \emph{routing} as the act of finding next hops,
and \emph{forwarding}, the act of sending a received packet through an
interface according to a \emph{routing table}. (Whether the routing table is
distinct from the network-layer forwarding table is an implementation detail.)
@ -74,7 +74,7 @@ particular class in text, it is only capitalised, as in \uv{The keys of the
dictionary are VertexIDs}.
For network diagrams, we use the Network topology icons from
Cisco\cite{cisco-icons}. The basic icons are shown on
Cisco~\cite{cisco-icons}. The basic icons are shown on
Figure~\ref{fig:basic-icons}.
\begin{figure}[h]
@ -104,11 +104,11 @@ Figure~\ref{fig:basic-icons}.
\addcontentsline{toc}{section}{Structure of the thesis}
In the \hyperref[ch:motivation]{first} chapter, we explore various approaches of visualising and
monitoring a network system. Then, in chapter \ref{ch:analysis}, we understand the
monitoring a network system. Then, in chapter~\ref{ch:analysis}, we understand the
behaviour of relevant networking technologies. From that, we derive a design
for Bidrvisu in chapter \ref{ch:design}. Chapter \ref{ch:usage} explains usage
of the program. At the end, we demonstrate how the project works in network
systems of various sizes.
for Birdvisu in chapter~\ref{ch:design}. Chapter~\ref{ch:usage} explains the usage
of the program. At the \hyperref[ch:evaluation]{end}, we discuss how the
project copes with topologies of network systems of various sizes.
%- motivation
% -tgt audience of birdvisu

@ -24,15 +24,71 @@
\include{glossary}
\chapwithtoc{List of Abbreviations}\label{ch:abbrs}
\XXX{In mathematical theses, it could be better to move the list of abbreviations to the beginning of the thesis.}
\XXX{TODO}
\bgroup
\parindent=0pt
\begin{small}
ABR -- Area border router
API -- Application programming interface
AS -- Autonomous system
BIRD -- BIRD Internet Routing Daemon -- BIRD Internet Routing Daemon Inter\dots
CIDR -- Classless inter-domain routing
DAG -- Directed acyclic graph
DR -- Designated router
GUI -- Graphical user interface
IP -- Internet protocol
ISP -- Internet service provider
LSA -- Link state advertisement
OSPF -- Open shortest path first
PTP -- Point-to-point
PyPI -- Python package index
RFC -- Request for comments
SMTP -- Simple mail transfer protocol
UI -- User interface
UNIX is not an abbreviation, but rather a trademark of The Open Group.
\end{small}
\egroup
\appendix
\chapter{Attachments}
\XXX{Attachments to the bachelor thesis, if any. Each attachment must be referred to at least once from the text of the thesis. Attachments are numbered.}
\XXX{The printed version should preferably contain attachments, which can be read (additional tables and charts, supplementary text, examples of program output, etc.). The electronic version is more suited for attachments which will likely be used in an electronic form rather than read (program source code, data files, interactive charts, etc.). Electronic attachments should be uploaded to SIS and optionally also included in the thesis on a~CD/DVD. Allowed file formats are specified in provision of the rector no. 72/2017.}
\section{First Attachment}
All attachments to this thesis are only in the electronic version. Readers of the paper version can find them on the internet
\section{Birdvisu}\label{att:birdvisu}
The Birdvisu project is located in the \verb|birdvisu| directory of the attached ZIP file.
Attached as of commit \verb|4abc3cc8|.
Available online at \url{https://gitea.ledoian.cz/LEdoian/birdvisu}.
\section{Gennet}\label{att:gennet}
The Gennet project is located in the \verb|gennet| directory of the attached ZIP file.
Attached as of commit \verb|4d604955|.
Available online at \url{https://gitea.ledoian.cz/LEdoian/gennet}.
\openright
\end{document}

@ -2,6 +2,6 @@
\Author{Pavel Turinský}
\Title{Visualizing OSPF topology}
\Keywords{keywords\sep more such\sep yet another}
\Subject{Abstract of thesis}
\Keywords{OSPF\sep network visualisation\sep routing\sep BIRD}
\Subject{Network administrators need to be aware of the state of their network. While link-state routing protocols like OSPF have the required information, there was no easy way to present it to the administrator. To solve this problem, we developed Birdvisu, a program to visualise the topology as seen by the BIRD Internet Routing Daemon. Our approach allows the topology to be easily annotated with other data, providing an extensible way of analysing the topology. While not fully featured yet, Birdvisu helped discover several misconfigurations in a community-run network connecting about 1600 people.}
\Publisher{Charles University}

@ -41,12 +41,6 @@ Prague \YearSubmitted
\end{center}
\newpage
\XXX{Bound into the introductory part must be the form with signed approval of the thesis topic (a photocopy suffices). This is not a~part of the electronic version of the thesis, do not scan!}
%%% A page with a solemn declaration to the bachelor thesis
\openright
\hypersetup{pageanchor=true}
\pagestyle{plain}
@ -110,7 +104,6 @@ Abstract:
Keywords:
\Keywords
\XXX{This information must be stored as PDF meta-data, too. Please refer to the {\tt README} file.}
\vss}
\newpage

Binary file not shown.

@ -25,14 +25,14 @@
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.1893044"
inkscape:cx="338.01271"
inkscape:cy="224.92139"
inkscape:cx="326.24112"
inkscape:cy="225.76222"
inkscape:window-width="1920"
inkscape:window-height="1167"
inkscape:window-x="1024"
inkscape:window-y="1094"
inkscape:window-maximized="1"
inkscape:current-layer="svg5" /><defs
inkscape:current-layer="layer2" /><defs
id="defs2"><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath18"><path
@ -58,7 +58,14 @@
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -301.54443,180.97854 27.718,-44.1197 28.27636,-12.62608"
id="path2078"
sodipodi:nodetypes="ccc" /></g><g
sodipodi:nodetypes="ccc" /><path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -331.5509,152.57644 -19.19852,12.83071"
id="path523"
transform="translate(5.8333333e-6)" /><path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -215.8155,151.41976 21.72488,-15.26896 20.09787,15.26897"
id="path526" /></g><g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="labels"
@ -268,7 +275,7 @@
x="-222.99622"
y="185.21698">B</tspan></text></g><g
id="g1884"
transform="translate(0.52916667,-2.1936684)"><g
transform="translate(1.18167,-14.452138)"><g
id="g496"
clip-path="url(#clipPath18-3)"
transform="matrix(0.03527778,0,0,-0.03527778,-201.8314,156.89231)"><path
@ -345,7 +352,7 @@
x="-275.5849"
y="203.62701">F</tspan></text></g><g
id="g1686"
transform="translate(2.2946826,-4.6175891)"><g
transform="translate(5.172061,8.896831)"><g
id="g1730"><g
id="g676"
clip-path="url(#clipPath18-3)"

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 56 KiB

@ -0,0 +1,4 @@
all: dot.pdf neato.pdf circo.pdf sfdp.pdf fdp.pdf twopi.pdf
%.pdf: source.dot
$* -Tpdf -o$@ $<

@ -0,0 +1,16 @@
graph "This is not good" {
rou_x -- {net_7 net_6};
rou_a -- {net_6 net_4};
rou_b -- {net_6 net_5};
rou_c -- {net_4 net_2};
rou_d -- {net_4 net_3};
rou_e -- {net_5 net_2};
rou_f -- {net_5 net_3};
rou_g -- {net_3 net_1};
rou_h -- {net_2 net_1};
rou_i -- {net_1};
pm -- {internet vl16};
qs -- {internet vl16};
tr -- {internet vl15 vl16 vl2 vl42};
zr -- {net_7 vl101 vl16};
}
Loading…
Cancel
Save