Skip to content
This repository has been archived by the owner on Sep 7, 2020. It is now read-only.

Commit

Permalink
transport: use new InterfaceStateMonitor
Browse files Browse the repository at this point in the history
https://jira.prplfoundation.org/browse/PPM-18

Use the InterfaceStateMonitor class in the ieee1905_transport process
as a new mechanism to detect changes in the state of the network
interfaces.

Signed-off-by: Mario Maz <[email protected]>
  • Loading branch information
mariomaz committed Jul 31, 2020
1 parent 00aca81 commit ce1b44b
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 53 deletions.
65 changes: 24 additions & 41 deletions framework/transport/ieee1905_transport/ieee1905_transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,20 @@ static constexpr int listen_buffer_size = 10;
/////////////////////////////// Implementation ///////////////////////////////
//////////////////////////////////////////////////////////////////////////////

Ieee1905Transport::Ieee1905Transport(const std::shared_ptr<EventLoop> &event_loop)
: m_event_loop(event_loop)
Ieee1905Transport::Ieee1905Transport(
const std::shared_ptr<beerocks::net::InterfaceStateMonitor> &interface_state_monitor,
const std::shared_ptr<EventLoop> &event_loop)
: m_interface_state_monitor(interface_state_monitor), m_event_loop(event_loop)
{
}

void Ieee1905Transport::run()
bool Ieee1905Transport::start()
{
if (m_broker) {
LOG(ERROR) << "Failed to start 1905 transport: already started";
return false;
}

// Broker server UDS socket
auto server_socket = std::make_shared<SocketServer>(
std::string(TMP_PATH "/" BEEROCKS_BROKER_UDS), listen_buffer_size);
Expand All @@ -63,47 +70,23 @@ void Ieee1905Transport::run()
return true;
});

// init netlink socket
if (!open_netlink_socket()) {
MAPF_ERR("cannot open netlink socket.");
return;
m_interface_state_monitor->set_handler([&](uint32_t iface_index, bool iface_state) {
handle_interface_status_change(iface_index, iface_state);
});

return true;
}

bool Ieee1905Transport::stop()
{
if (!m_broker) {
LOG(ERROR) << "Failed to stop 1905 transport: not started";
return false;
}

// Create a shared_ptr socket wrapper for the netlink socket
auto netlink_socket = std::shared_ptr<Socket>(new Socket(netlink_fd_), [](Socket *socket) {
// Close the socket file descriptor
if (socket) {
close(socket->getSocketFd());
}
});
m_interface_state_monitor->set_handler(nullptr);

// Add the netlink socket into the broker's event loop
m_event_loop->register_handlers(netlink_socket->getSocketFd(),
{
// Accept incoming connections
.on_read =
[&](int fd, EventLoop &loop) {
LOG(DEBUG)
<< "incoming message on the netlink socket";
handle_netlink_pollin_event();
return true;
},

// Not implemented
.on_write = nullptr,

// Fail on server socket disconnections or errors
.on_disconnect =
[&](int fd, EventLoop &loop) {
LOG(ERROR) << "netlink socket disconnected";
return false;
},
.on_error =
[&](int fd, EventLoop &loop) {
LOG(ERROR) << "netlink socket error";
return false;
},
});
return true;
}

} // namespace transport
Expand Down
28 changes: 26 additions & 2 deletions framework/transport/ieee1905_transport/ieee1905_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <mapf/transport/ieee1905_transport_messages.h>

#include <bcl/beerocks_event_loop.h>
#include <bcl/network/interface_state_monitor.h>

#include "ieee1905_transport_broker.h"

Expand Down Expand Up @@ -58,12 +59,35 @@ class Ieee1905Transport {
/**
* Class constructor
*
* @param interface_state_monitor Interface state monitor to detect changes in the state of
* network interfaces (transitions to and from the up-and-running state).
* @param event_loop Event loop to wait for I/O events.
*/
explicit Ieee1905Transport(const std::shared_ptr<EventLoop> &event_loop);
void run();
Ieee1905Transport(
const std::shared_ptr<beerocks::net::InterfaceStateMonitor> &interface_state_monitor,
const std::shared_ptr<EventLoop> &event_loop);

/**
* @brief Starts the transport process.
*
* @return True on success and false otherwise.
*/
bool start();

/**
* @brief Stops the transport process.
*
* @return True on success and false otherwise.
*/
bool stop();

private:
/**
* Interface state monitor used by the process to detect changes in the state of network
* interfaces (transitions to and from the up-and-running state).
*/
std::shared_ptr<beerocks::net::InterfaceStateMonitor> m_interface_state_monitor;

/**
* Application event loop used by the process to wait for I/O events.
*/
Expand Down
81 changes: 71 additions & 10 deletions framework/transport/ieee1905_transport/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,93 @@
#include "ieee1905_transport.h"

#include <bcl/beerocks_event_loop_impl.h>
#include <bcl/network/interface_state_monitor_impl.h>
#include <bcl/network/sockets_impl.h>

#include <net/if.h>
#include <unistd.h>

using namespace beerocks;
using namespace beerocks::net;
using namespace beerocks::transport;

int main(int argc, char *argv[])
{
mapf::Logger::Instance().LoggerInit("transport");

/**
* Create NETLINK_ROUTE netlink socket for kernel/user-space communication.
*/
auto socket = std::make_shared<NetlinkRouteSocket>();

/**
* Create client socket.
* Bind it to route netlink multicast group to listen for multicast packets sent from the
* kernel containing network interface create/delete/up/down events.
*/
ClientSocketImpl<NetlinkRouteSocket> client(socket);
client.bind(NetlinkAddress(RTMGRP_LINK));

/**
* Create connection to send/receive data using this socket
*/
auto connection = std::make_shared<SocketConnectionImpl>(socket);

/**
* Create application event loop to wait for blocking I/O operations.
*/
auto event_loop = std::make_shared<EventLoopImpl>();

Ieee1905Transport ieee1905_transport(event_loop);
/**
* Create the interface state monitor.
*/
auto interface_state_monitor =
std::make_shared<InterfaceStateMonitorImpl>(connection, event_loop);

/**
* Application exit code: 0 on success and -1 on failure.
* From this point on, there's a single exit point to allow for start/stop methods to be
* cleanly called in pairs.
*/
int exit_code = 0;

/**
* Start the interface state monitor
*/
if (interface_state_monitor->start()) {
/**
* Create the IEEE1905 transport process.
*/
Ieee1905Transport ieee1905_transport(interface_state_monitor, event_loop);

ieee1905_transport.run();
/**
* Start the IEEE1905 transport process
*/
if (ieee1905_transport.start()) {

// Run the application event loop
MAPF_INFO("starting main loop...");
for (;;) {
if (event_loop->run() < 0) {
LOG(ERROR) << "Broker event loop failure!";
return -1;
// Run the application event loop
MAPF_INFO("starting main loop...");
while (0 == exit_code) {
if (event_loop->run() < 0) {
LOG(ERROR) << "Broker event loop failure!";
exit_code = -1;
}
}
MAPF_INFO("done");

ieee1905_transport.stop();

} else {
LOG(ERROR) << "Unable to start IEEE1905 transport process!";
exit_code = -1;
}

interface_state_monitor->stop();

} else {
LOG(ERROR) << "Unable to start interface state monitor!";
exit_code = -1;
}
MAPF_INFO("done");

return 0;
return exit_code;
}

0 comments on commit ce1b44b

Please sign in to comment.