Netwokring
Networking is available via lwip <https://www.nongnu.org/lwip/2_1_x/index.html> library onto which platform’s networking is built. By default, IPv6 protocol is used.
The networking is represented by the class NetworkManager
which enables user not only an easier control over network interfaces, their configuration, etc.,
but also provides additional functionality such as routing support. There should be always one
instance of the class running within a single module as the NetworkManager takes care of all
its connectors – within the networking, they are represented with Interface
– and there is an additional virtual interface (“rl0”) independent of physical connectors used as the main
interface of the module. This virtual interface is the interface you want to configure, if you don’t
know which one.
The usage is simple, the class itself initializes everything using RoFI.
For example, let us initialize networking of a module and assign an IPv6 address to it.
#include <networking/networkManager.hpp>
// ...
// if lwip's tcpip stack is not initialized, call
// tcpip_init( nullptr, nullptr );
hal::RoFI localRofi = RoFI::getLocalRoFI();
NetworkManager net( localRofi );
// adds address fc07:0:0:1::1 with mask /80 to interface "rl0", which is the virtual one
net.addAddress( "fc07:0:0:1::1"_ip, 80, net.interface( "rl0" ) );
// set all interfaces up -- to process incomming/outcomming traffic
net.setUp();
Now, we have a module with an IP address configured. Suppose, that we have a network of interconnected modules where each has its own address. To be able to send a message between two modules, the routing table of a receiver (and all modules in-between) has to contain a path to receiver. To populate the routing table, the routing protocol must be configured.
The RoFI platform offers multiple routing protocols by default; these are
SimplePeriodic, SimpleReactive,
and RRP. The first two protocols are very simple and they always share their whole
routing table. The main difference is the way messages are sent; the first one sends updates periodically, the second
one sends messages on network changes only. The third protocol tries to be smarter about sharing routing information;
more details can be found in the Protocols section.
Using SimpleReactive protocol, we enable routing with
#include <networking/protocols/simpleReactive.hpp>
// the code from above
// Add protocol into the NetworkManager so that it can be used
auto* simpleReactive = net.addProtocol( SimpleReactive() );
// now we enable the protocol on all interfaces
net.setProtocol( simpleReactive );
// you can also enable the protocol only on certain interfaces
// e.g., to enable the protocol on interface "rd4", you can call
// net.setProtocol( simpleReactive, net.getInterface( "rd4" ) );
//
// you could also accomplish the same as above with a for loop
// for ( const auto& i : net.interfaces() ) {
// net.setProtocol( simpleReactive, net.interface( i.name() ) );
// }
//
The routing process is now running, so the interconnected modules will share necessary information and populate the routing table. Then you can use regular sockets from lwip library and send messages accross the network.
Network Manager
-
class NetworkManager
Public Functions
-
NetworkManager() = delete
-
inline explicit NetworkManager(hal::RoFI rofi)
Create a Network Manager instance for module corresponding to given RoFI proxy.
This constructor creates MAC adress from the proxy’s id.
-
inline NetworkManager(hal::RoFI rofi, PhysAddr p)
Create a Network Manager instance for module corresponding to given RoFI proxy.
This constructor uses
pas the MAC address.
-
inline const Interface *findInterface(const Interface::Name &name) const
Finds an interface of given name among Network Manager’s interfaces.
-
inline const Interface &interface(const Interface::Name &name) const
Returns an interface of given name.
The interface must exist within Network Manager.
-
inline auto interfaces() const
Get iterable range of interfaces within the Network Manager.
-
template<std::derived_from<Protocol> Proto>
inline Protocol *addProtocol(const Proto &p) Add given protocol into the Network Manager.
There must NOT be a protocol with same name and/or listenner address present in the Network Manager.
- Parameters:
p – protocol to add
- Returns:
Pointer to the added instance under control of the Network Manager.
-
inline auto protocols() const
Get iterable range of protocols within the Network Manager.
-
inline bool addAddress(const Ip6Addr &ip, uint8_t mask, const Interface &i)
Add given address and mask onto a given interface.
- Returns:
true if the address was added succesfully
- Returns:
false otherwise
-
inline bool removeAddress(const Ip6Addr &ip, uint8_t mask, const Interface &i)
Remove given address and mask from the given interface.
- Returns:
true if the address was removed succesfully
- Returns:
false otherwise
-
inline Protocol *getProtocol(const std::string &name)
Get protocol of a given name.
Names are unique within the protocol.
- Returns:
a pointer to a protocol of a given name
-
inline void setProtocol(Protocol &proto, const Interface &i)
Set protocol to run on a given interface.
This sets up all necessary listeners, starts processing protocol messages, etc.
-
inline void removeProtocol(Protocol &proto, const Interface &i)
Remove protocol from the given interface.
This unsets all listeners, stops processing protocol’s messages.
-
inline void setUp(const Interface &i)
Set the interface up.
The interface starts processing trafic.
-
inline void setUp()
Set all interfaces up.
-
inline void setDown(const Interface &i)
Set the interface down.
The interface stops processing trafic.
-
inline void setDown()
Set all interfaces down.
-
inline const RoutingTable &routingTable() const
Get network manager’s routing table.
-
inline bool addRoute(const Ip6Addr ip, uint8_t mask, const Interface::Name &ifname, RoutingTable::Cost cost)
Add a static route into the routing table.
- Returns:
true if the route was succesfully added
- Returns:
false if the interface does not exist or the route was not added
-
inline bool rmRoute(const Ip6Addr ip, uint8_t mask, const Interface::Name &ifname)
Remove a static route into the routing table.
- Returns:
true if the route was succesfully removed
- Returns:
false if the interface does not exist or the route was not removed
-
inline void log(Logger::Level l, const std::string &msg)
Logs a given message with corresponding severity level.
-
inline void log(Logger::Level l, const std::string &where, const std::string &msg)
Logs a given message with corresponding severity level specifying the component where the event originated.
-
inline auto logs() const
Returns an iterable range of logs.
-
inline auto logsFrom(const Interface &i) const
Returns an iterable range of logs only from the specified component.
-
inline auto logs(Logger::Level l) const
Returns an iterable range of logs with given severity level.
-
NetworkManager() = delete
Protocols
The interface is desribed by the class :cpp:class`Protocol <rofi::net::Protocol>`
-
class Protocol
Virtual class defining the interface for NetworkManager’s protocols.
Subclassed by rofi::net::LeaderElect, rofi::net::MessageDistributor, rofi::net::RRP, rofi::net::SimplePeriodic, rofi::net::SimpleReactive
Public Types
-
enum class Route
Enum for communicating the route updates.
Values:
-
enumerator ADD
A new route to be added.
-
enumerator RM
A known route is no longer valid.
-
enumerator ADD
-
enum class ConfigAction
Enum for communicating the interface state updates.
Values:
-
enumerator RESPOND
A response on obtained update is needed.
-
enumerator RESPOND
-
using RoutingTableFun = std::function<RoutingTable::Records()>
Public Functions
-
virtual ~Protocol() = default
-
virtual bool onMessage(const std::string &interfaceName, hal::PBuf packet) = 0
Process the incomming message on given interface.
- Returns:
true if if a change of state is required.
-
inline virtual bool onInterfaceEvent(const Interface&, bool)
This function is called when an event (Connected, Disconnected) on connector arises.
- Parameters:
interface – on which event originated
connected – true if a connector was connected, false if it was disconnected
- Returns:
true if any the event caused any changes.
-
virtual bool afterMessage(const Interface &i, std::function<void(PBuf&&)> f, void *args) = 0
This function is called after processing updates from onMessage (if any) and provides to the protocol the ability of sending a message via given interface.
- Returns:
bool indicating if any local change is required to take place.
-
inline virtual bool hasRouteUpdates() const
Function that returns true if there are any pending routing updates.
-
inline virtual std::vector<std::pair<Route, RoutingTable::Record>> getRouteUpdates() const
Function that outputs all routing updates possibly created in
onMessage.This function is called in case
onMessageandhasRouteUpdatesreturntrue. The default implementation returns an empty vector, so it is not necessary to override this for non-routing protocols.- Returns:
A vector of pairs with the type of change (e.g., a new route) and its RoutingTable::Record to be added.
-
inline virtual bool hasConfigUpdates() const
Function that returns true if there are any pending configuration updates.
-
inline virtual std::vector<std::pair<ConfigAction, ConfigChange>> getConfigUpdates() const
Function that outputs all interface/state related updates possibly created in
onMessageThis function is called in case
onMessageandhasConfigUpdatesreturntrue. The default imlementation return an empty vector, so it is not necessary to override this for routing-only protocols.- Returns:
A vector of pairs with the type of change (e.g., a new IP) and its
ConfigChangewith all necessary information.
-
virtual void clearUpdates() = 0
Clear any (cached) updates.
This function should clear all the updates within the protocol. By calling this function, the NetworkManager signalizes that all the updates (both – routing and interface related) were gathered already and are no longer needed.
-
inline virtual bool addAddressOn(const Interface&, const Ip6Addr&, uint8_t)
Indicate a new address on given interface.
- Returns:
true if any change was caused by this change.
-
inline virtual bool rmAddressOn(const Interface&, const Ip6Addr&, uint8_t)
Indicate a removal of an address on given interface.
- Returns:
true if any change was caused by this change.
-
virtual bool addInterface(const Interface &interface) = 0
Add the given interface into the protocol.
- Returns:
true if the interface was succesfully added.
-
virtual bool removeInterface(const Interface &interface) = 0
Remove the given interface from the protocol.
- Returns:
true if the interface was succesfully removed.
-
virtual bool manages(const Interface &interface) const = 0
Given an interface, decide if it is managed by the protocol.
Namely, it should hold that after adding an interface via
addInterfacewhich returns true, thenmanagesshould return true for such interface.- Returns:
true if the interface is managed by the protocol.
-
inline void setRoutingTableCB(RoutingTableFun f)
This function can set the callback for the routing table.
The callback itself should be a function that returns the current state of the table for given protocol – records learned through it.
-
inline RoutingTable::Records routingTableCB() const
Function that outputs all the records from routing table related to the protocol.
Internally, it uses the callback set in
setRoutingTableCBfunction. If any such function is provided, then this function returns an empty collection.
-
virtual Ip6Addr address() const = 0
Returns a multicast IP on which the protocol listener will be running.
This should be unique for each protocol.
-
virtual std::string name() const = 0
Returns a name of the protocol.
This should be unique for each protocol.
-
inline virtual std::string info() const
Returns a string representing some basic information about the protocol (e.g., its name and listenner address).
-
enum class Route
And there are some default implementations. For routing we have
-
class SimplePeriodic : public rofi::net::Protocol
Proof-of-concept routing protocol using IP layer only with periodic messages.
Public Functions
-
inline SimplePeriodic()
-
inline SimplePeriodic(int period)
-
inline virtual bool onMessage(const std::string &interfaceName, rofi::hal::PBuf packetWithHeader) override
-
inline virtual bool afterMessage(const Interface &i, std::function<void(PBuf&&)> f, void *args) override
This function is called after processing updates from onMessage (if any) and provides to the protocol the ability of sending a message via given interface.
- Returns:
bool indicating if any local change is required to take place.
-
inline virtual bool onInterfaceEvent(const Interface &interface, bool connected) override
This function is called when an event (Connected, Disconnected) on connector arises.
- Parameters:
interface – on which event originated
connected – true if a connector was connected, false if it was disconnected
- Returns:
true if any the event caused any changes.
-
inline virtual bool hasRouteUpdates() const override
Function that returns true if there are any pending routing updates.
-
inline virtual std::vector<std::pair<Route, RoutingTable::Record>> getRouteUpdates() const override
Function that outputs all routing updates possibly created in
onMessage.This function is called in case
onMessageandhasRouteUpdatesreturntrue. The default implementation returns an empty vector, so it is not necessary to override this for non-routing protocols.- Returns:
A vector of pairs with the type of change (e.g., a new route) and its RoutingTable::Record to be added.
-
inline virtual void clearUpdates() override
Clear any (cached) updates.
This function should clear all the updates within the protocol. By calling this function, the NetworkManager signalizes that all the updates (both – routing and interface related) were gathered already and are no longer needed.
-
inline virtual bool addAddressOn(const Interface &interface, const Ip6Addr &ip, uint8_t mask) override
Indicate a new address on given interface.
- Returns:
true if any change was caused by this change.
-
inline virtual bool rmAddressOn(const Interface &interface, const Ip6Addr &ip, uint8_t mask) override
Indicate a removal of an address on given interface.
- Returns:
true if any change was caused by this change.
-
inline virtual bool addInterface(const Interface &interface) override
Add the given interface into the protocol.
- Returns:
true if the interface was succesfully added.
-
inline virtual bool removeInterface(const Interface &interface) override
Remove the given interface from the protocol.
- Returns:
true if the interface was succesfully removed.
-
inline virtual bool manages(const Interface &interface) const override
Given an interface, decide if it is managed by the protocol.
Namely, it should hold that after adding an interface via
addInterfacewhich returns true, thenmanagesshould return true for such interface.- Returns:
true if the interface is managed by the protocol.
-
inline virtual Ip6Addr address() const
Returns a multicast IP on which the protocol listener will be running.
This should be unique for each protocol.
-
inline virtual std::string name() const
Returns a name of the protocol.
This should be unique for each protocol.
-
inline SimplePeriodic()
-
class SimpleReactive : public rofi::net::Protocol
Proof-of-concept routing protocol using IP layer only with reactive messages.
Public Functions
-
inline virtual bool onMessage(const std::string &interfaceName, rofi::hal::PBuf packetWithHeader) override
-
inline virtual bool afterMessage(const Interface &i, std::function<void(PBuf&&)> f, void*) override
This function is called after processing updates from onMessage (if any) and provides to the protocol the ability of sending a message via given interface.
- Returns:
bool indicating if any local change is required to take place.
-
inline virtual bool onInterfaceEvent(const Interface &interface, bool connected) override
This function is called when an event (Connected, Disconnected) on connector arises.
- Parameters:
interface – on which event originated
connected – true if a connector was connected, false if it was disconnected
- Returns:
true if any the event caused any changes.
-
inline virtual bool hasRouteUpdates() const override
Function that returns true if there are any pending routing updates.
-
inline virtual std::vector<std::pair<Route, RoutingTable::Record>> getRouteUpdates() const override
Function that outputs all routing updates possibly created in
onMessage.This function is called in case
onMessageandhasRouteUpdatesreturntrue. The default implementation returns an empty vector, so it is not necessary to override this for non-routing protocols.- Returns:
A vector of pairs with the type of change (e.g., a new route) and its RoutingTable::Record to be added.
-
inline virtual void clearUpdates() override
Clear any (cached) updates.
This function should clear all the updates within the protocol. By calling this function, the NetworkManager signalizes that all the updates (both – routing and interface related) were gathered already and are no longer needed.
-
inline virtual bool addAddressOn(const Interface &interface, const Ip6Addr &ip, uint8_t mask) override
Indicate a new address on given interface.
- Returns:
true if any change was caused by this change.
-
inline virtual bool rmAddressOn(const Interface &interface, const Ip6Addr &ip, uint8_t mask) override
Indicate a removal of an address on given interface.
- Returns:
true if any change was caused by this change.
-
inline virtual bool addInterface(const Interface &interface) override
Add the given interface into the protocol.
- Returns:
true if the interface was succesfully added.
-
inline virtual bool removeInterface(const Interface &interface) override
Remove the given interface from the protocol.
- Returns:
true if the interface was succesfully removed.
-
inline virtual bool manages(const Interface &interface) const override
Given an interface, decide if it is managed by the protocol.
Namely, it should hold that after adding an interface via
addInterfacewhich returns true, thenmanagesshould return true for such interface.- Returns:
true if the interface is managed by the protocol.
-
inline virtual Ip6Addr address() const
Returns a multicast IP on which the protocol listener will be running.
This should be unique for each protocol.
-
inline virtual std::string name() const
Returns a name of the protocol.
This should be unique for each protocol.
-
inline virtual bool onMessage(const std::string &interfaceName, rofi::hal::PBuf packetWithHeader) override
-
class RRP : public rofi::net::Protocol
Public Types
-
using Cost = uint8_t
Public Functions
-
virtual ~RRP() = default
-
inline virtual bool afterMessage(const Interface &i, std::function<void(PBuf&&)> f, void*) override
This function is called after processing updates from onMessage (if any) and provides to the protocol the ability of sending a message via given interface.
- Returns:
bool indicating if any local change is required to take place.
-
inline virtual bool onInterfaceEvent(const Interface &interface, bool connected) override
This function is called when an event (Connected, Disconnected) on connector arises.
- Parameters:
interface – on which event originated
connected – true if a connector was connected, false if it was disconnected
- Returns:
true if any the event caused any changes.
-
inline virtual bool hasRouteUpdates() const override
Function that returns true if there are any pending routing updates.
-
inline virtual std::vector<std::pair<Route, RoutingTable::Record>> getRouteUpdates() const override
Function that outputs all routing updates possibly created in
onMessage.This function is called in case
onMessageandhasRouteUpdatesreturntrue. The default implementation returns an empty vector, so it is not necessary to override this for non-routing protocols.- Returns:
A vector of pairs with the type of change (e.g., a new route) and its RoutingTable::Record to be added.
-
inline virtual void clearUpdates() override
Clear any (cached) updates.
This function should clear all the updates within the protocol. By calling this function, the NetworkManager signalizes that all the updates (both – routing and interface related) were gathered already and are no longer needed.
-
inline virtual bool addAddressOn(const Interface &interface, const Ip6Addr &ip, uint8_t mask) override
Indicate a new address on given interface.
- Returns:
true if any change was caused by this change.
-
inline virtual bool rmAddressOn(const Interface &interface, const Ip6Addr &ip, uint8_t mask) override
Indicate a removal of an address on given interface.
- Returns:
true if any change was caused by this change.
-
inline virtual bool addInterface(const Interface &interface) override
Add the given interface into the protocol.
- Returns:
true if the interface was succesfully added.
-
inline virtual bool removeInterface(const Interface &interface) override
Remove the given interface from the protocol.
- Returns:
true if the interface was succesfully removed.
-
inline virtual bool manages(const Interface &interface) const override
Given an interface, decide if it is managed by the protocol.
Namely, it should hold that after adding an interface via
addInterfacewhich returns true, thenmanagesshould return true for such interface.- Returns:
true if the interface is managed by the protocol.
-
inline virtual rofi::hal::Ip6Addr address() const override
Returns a multicast IP on which the protocol listener will be running.
This should be unique for each protocol.
-
inline virtual std::string name() const override
Returns a name of the protocol.
This should be unique for each protocol.
-
inline virtual std::string info() const override
Returns a string representing some basic information about the protocol (e.g., its name and listenner address).
-
using Cost = uint8_t
and there is also a simple leader elect protocol available
-
class LeaderElect : public rofi::net::Protocol
Proof-of-concept of a leader election protocol using IP layer only.
Public Functions
-
inline LeaderElect(int id, const Ip6Addr &leaderAddr, uint8_t mask)
-
virtual ~LeaderElect() = default
-
inline virtual bool afterMessage(const Interface &i, std::function<void(PBuf&&)> f, void*)
This function is called after processing updates from onMessage (if any) and provides to the protocol the ability of sending a message via given interface.
- Returns:
bool indicating if any local change is required to take place.
-
inline virtual bool hasConfigUpdates() const override
Function that returns true if there are any pending configuration updates.
-
inline virtual std::vector<std::pair<ConfigAction, ConfigChange>> getConfigUpdates() const
Function that outputs all interface/state related updates possibly created in
onMessageThis function is called in case
onMessageandhasConfigUpdatesreturntrue. The default imlementation return an empty vector, so it is not necessary to override this for routing-only protocols.- Returns:
A vector of pairs with the type of change (e.g., a new IP) and its
ConfigChangewith all necessary information.
-
inline virtual void clearUpdates()
Clear any (cached) updates.
This function should clear all the updates within the protocol. By calling this function, the NetworkManager signalizes that all the updates (both – routing and interface related) were gathered already and are no longer needed.
-
inline virtual bool addInterface(const Interface &interface)
Add the given interface into the protocol.
- Returns:
true if the interface was succesfully added.
-
inline virtual bool removeInterface(const Interface &interface)
Remove the given interface from the protocol.
- Returns:
true if the interface was succesfully removed.
-
inline virtual bool manages(const Interface &interface) const override
Given an interface, decide if it is managed by the protocol.
Namely, it should hold that after adding an interface via
addInterfacewhich returns true, thenmanagesshould return true for such interface.- Returns:
true if the interface is managed by the protocol.
-
inline virtual Ip6Addr address() const override
Returns a multicast IP on which the protocol listener will be running.
This should be unique for each protocol.
-
inline virtual std::string name() const override
Returns a name of the protocol.
This should be unique for each protocol.
-
inline virtual std::string info() const override
Returns a string representing some basic information about the protocol (e.g., its name and listenner address).
-
inline LeaderElect(int id, const Ip6Addr &leaderAddr, uint8_t mask)
Command Line Interface (CLI)
Simple CLI interface for the network management is availabe.
-
class NetworkManagerCli
Class for CLI management for NetworkManager class.
Public Functions
-
inline NetworkManagerCli(NetworkManager &netManager)
-
inline bool command(const std::string &cmd)
Process given command and makes appropriate changes to underlying NetworkManager.
- Returns:
true if the command was succesfully parsed.
-
inline bool command(std::istream &ss)
Overloaded variant of the previous
commandfunction.
-
inline void help() const
Prints out help message containing the usage description.
-
inline NetworkManagerCli(NetworkManager &netManager)
Components
The rest of components are listed here. The user will encouter them, but changes in their configuration should be done indirectly via NetworkManager.
- Interface
InterfaceInterface::DHCPInterface::NameInterface::Interface()Interface::Interface()Interface::~Interface()Interface::Interface()Interface::operator=()Interface::setUp()Interface::setDown()Interface::isUp()Interface::isDown()Interface::isConnected()Interface::isVirtual()Interface::setProtocol()Interface::removeProtocol()Interface::sendProtocol()Interface::getAddress()Interface::getAddress()Interface::name()Interface::setName()Interface::addAddress()Interface::removeAddress()Interface::send()Interface::dataSent()Interface::dataReceived()Interface::operator==()Interface::operator<<()
- Routing table
RoutingTableRoutingTable::CostRoutingTable::RecordsRoutingTable::size()RoutingTable::empty()RoutingTable::find()RoutingTable::add()RoutingTable::add()RoutingTable::remove()RoutingTable::remove()RoutingTable::removeNetwork()RoutingTable::removeInterface()RoutingTable::purge()RoutingTable::recordsLearnedFrom()RoutingTable::operator<<()RoutingTable::GatewayRoutingTable::RecordRoutingTable::Record::Record()RoutingTable::Record::Record()RoutingTable::Record::addGateway()RoutingTable::Record::addGateway()RoutingTable::Record::removeGateway()RoutingTable::Record::removeGateway()RoutingTable::Record::removeGateway()RoutingTable::Record::ip()RoutingTable::Record::mask()RoutingTable::Record::size()RoutingTable::Record::best()RoutingTable::Record::contains()RoutingTable::Record::gateways()RoutingTable::Record::compareNetworks()RoutingTable::Record::compareNetworks()RoutingTable::Record::operator<=>()