Skip to content
Eduard Grasa edited this page Aug 29, 2018 · 12 revisions

Table of contents

  1. Introduction
  2. User-space plugins tutorial
    • 2.1 Plugin.cc
    • 2.2 sm-example.cc
    • 2.3 sm-example.manifest

1. Introduction

The purpose of this section is to present some simple but complete examples that illustrate how to write user-space and kernel-space plugins. These tutorials are aligned to the current version of the SDK.

2. User-space plugins tutorial

Although it is possible to develop user-space plugins within the rinad/ipcp source code tree, the preferred way of contributing custom plugins to the IPC Process user-space implementation is to develop them outside of the rinad/ipcp source tree. Consequently, this tutorial will focus on this case.

A user-space plugin contains the implementation of one or more policy-sets that will be made available to the IPC Process Daemon at runtime by dynamically linking the shared object containing the plugin. The recommended structure of a plugin consists of the following files, that are usually contained in a directory dedicated to the plugin:

  • plugin.cc. The source file containing code that exports the policy-set factories for all the policy-sets contributed by the plugin.
  • implementation.cc. A number of .cc and .h files containing the implementation of the policy-sets contributed by the plugin.
  • plugin-name.manifest. A text file in JSON format that provides information on the policy-sets contributed by the plugin (see Section 4.3).
  • makefiles. A build system to compile, link and install the plugin. For example, it may be a single Makefile, or more files for autoconf/automake ([autoconf],[autoconf]) or CMake.

In order to understand better how all pieces works together, this section will walk through an example of a simple plugin that contributes a single policy-set to the Security-Manager component of the IPCP Daemon. The plugin, which can be found in the plugins/example-smplugin directory of the IRATI repository, is made of the following files:

  • plugin.cc
  • sm-example.cc
  • sm-example.manifest
  • Makefile

2.1 Plugin.cc

#include <string>
#include <sstream>
#define IPCP_MODULE "security-manager-example-ps"
#include "ipcp-logging.h"
#include "components.h"

namespace rinad {

extern "C" rina::IPolicySet * createSecurityManagerExamplePs(rina::ApplicationEntity * ctx);
extern "C" void destroySecurityManagerExamplePs(rina::IPolicySet * ps);
extern "C" int get_factories(std::vector<struct rina::PsFactory>& factories)
{
    struct rina::PsFactory factory;
    factory.info.name = "example";
    factory.info.app_entity = rina::ApplicationEntity::SECURITY_MANAGER_AE_NAME;
    factory.create = createSecurityManagerExamplePs;
    factory.destroy = destroySecurityManagerExamplePs;
    factories.push_back(factory);
    return 0;
}

} // namespace rinad

This file carries out the following important tasks:

  • Inclusion of components.h, which contains the definitions of several IPC Process Daemon base classes and data structures. Among the others, there are the definitions of the base class for the Security Manager policy-sets, and the base class for all IPCP components.
  • For each policy-set that the plugin contributes (one in this example), plugin.cc declares one function to create an instance of the policy-set.
  • For each policy-set that the plugin contributes (one in this example), plugin.cc declares one function to destroy an instance of the policy-set.
  • The definition of a get_factories function to export the policy-set factories. For each factory to be exported (in this case only one), a rina::PsFactory object instance is added to the output array passed as argument. Each entry in the array is built with the policy-set name, the IPC Process component (Application Entity) the policy set is part of (Security Manager in this case), and the references to the factory’s create and destroy functions.

2.2 sm-example.cc

#include <string>
#include <sstream>

#define IPCP_MODULE "security-manager-example-ps"
#include "ipcp-logging.h"
#include "components.h"

namespace rinad {

class SecurityManagerExamplePs: public ISecurityManagerPs {
public:
    SecurityManagerExamplePs(IPCPSecurityManager * dm);
    bool isAllowedToJoinDIF(const rina::Neighbor& newMember);
    bool acceptFlow(const Flow& newFlow);
    int set_policy_set_param(const std::string& name, const std::string& value);
    virtual ~SecurityManagerExamplePs() {}
private:
    // Data model of the security manager component.
    IPCPSecurityManager * dm;
    int max_retries;
};

// [...]

extern "C" rina::IPolicySet * createSecurityManagerExamplePs(rina::ApplicationEntity * ctx)
{
    IPCPSecurityManager * sm = dynamic_cast<IPCPSecurityManager *>(ctx);

    if (!sm) {
        return NULL;
    }

    return new SecurityManagerExamplePs(sm);
}

extern "C" void destroySecurityManagerExamplePs(rina::IPolicySet * ps)
{
    if (ps) {
        delete ps;
    }
}

} // namespace rinad

This file carries out the following tasks:

  • Definition of a class that inherits from the abstract class ISecurityManagerPS, which is the base class for all the Security Manager policy-sets. Such a class needs to provide an implementation for the isAllowedToJoinDIF and acceptFlow operations. We have omitted those dummy implementations from the listing since it is not important for the purpose of illustrating the SDK usage.
  • Definition of the policy factory’s create function, declared in plugin.cc. An IPCP component (or application entity) is passed as a parameter, and is downcasted to the object of type IPCPSecurityManager. Then a new instance of the SecurityManagerExamplePs class is created and returned to the caller.
  • Definition of the destroy operation that deletes the instance of the policy set.

2.3 sm-example.manifest

{
    "PluginName": "sm-example",
    "PluginVersion": "1",
    "PolicySets" : [
    {
        "Name": "example",
        "Component": "security-manager",
        "Version" : "1"
    }
    ]
}

The plugin manifest contains the name and version of the plugin as well as the name, component and version of all the policy-sets contributed by the plugin (just one in this case).

Clone this wiki locally