Network Simulator is the most complex feature of Patriot framework. It implements logic necessary to deploy virtual network environment where the parts of System Under Test, or whole SUT, can be deployed. In the current state of the framework, the network simulation is done with the Docker container platform.

The Docker container platform is containerization platform aiming to bring several enhancements to the application deployment and its lifecycle. The core concept of containerization is to build a system for deployment of applications, that allows software delivery independent of the platform, advanced sandboxing of the applications. In case of Docker this is achieved by Paravirtualization, where the application is using only the kernel of the operating system and its core features, but all other services (e.g. networking, storage) are allocated for the containerized process and process is as separated from other processes as possible.

Following terms are necessary to understand the implementation of the network simulator.

  • Docker image - is bundled application with all necessary dependencies for application execution.

  • Docker container - running instance of application, unit that has its own separated virtual drive initialized with data from image, using Copy-on-write strategy.

  • Docker network - a virtual network that provides network interfaces to the docker containers and interconnects or separates them from one another.

The Patriot framework embraces those properties and builds on top of them scalable solution, that allows preparing, deploy and test components of the System Under Test.

Router

One of the necessary parts for the Network Simulation is a component called a router. The router is in general device, which connects together two or more networks on L3 ISO/OSI level, (network level). That means that routers are responsible for providing service on the level of IP protocol instead of L2 ethernet. The main functionality of a router is to pass the data from one network to another based on their target network. To achieve this the routers must be equipped with routing tables.

A routing table is set of rules that define to which network should be data holder, in case of IP called packet, passed by its target.

The router component of Patriot framework is implemented in the patriot-router module. This the module implements a software router with RESTfull API, which allows Patriot framework to set it up and control its behavior.

Building router Docker image
docker pull patriotframework/patriot-router:latest

This step will pull an image stored in the DockerHub, which is ready to use for the Patriot framework router. If you want to do any modification of routers behavior you can do it via Dockerfile, but CMD and ENTRYPOINT must stay ! After you build your routers image, you have to set tag to the io.patriot_framework.router property. After the router is built or pulled, the Network Simulator has all the dependencies ready for the execution.

Application

Application has to be build on base image from patriotframework docker hub. You can modify your application container, but stay must same. Java and go are fully installed in base image. Specify CMD with command which will run your java application. After all modifications are done, you have to build image from your Dockerfile. Tag used for building image will be later used for deploying application to topology.

Pulling application base image
docker pull patriotframework/simulator-base:latest
Updating Dockerfile
FROM patriotframework/simulator-base:latest
CMD["java", "-jar", "generator.jar", "-c", "config.yaml"]
Building docker image
docker build -t MY_TAG DOCKERFILE_DIRECTORY

Basic scenario

The basic scenario shows how the network topology is set up within Network Simulator and how the components are integrated to achieve the desired outcome. The scenario can be broke down into the following steps.

  1. Define network topology which is the high-level connection of the networks, it allows networks to be built into the tree structure.

    1. Define routers that will interconnect the virtual networks

    2. Define networks that will be interconnected in the topology

    3. Define routes between networks

  2. Call manager to deploy topology

Those steps should be used in the series as is defined before because it will not cause possible errors due to missed dependencies.

Defining routers

The first step is to define needed routers in the Patriot framework context, which will later connect networks together into the desired topology. These objects are only blueprints for the Network Simulator runtime, hence the only attribute for the router in this step is only its name of type String. For later use, these Router objects can be build with RouterBuilder.

Creation of router
import io.patriot_framework.network.simulator.api.model.devices.router.RouterImpl;
RouterImpl r = new RouterIml("TRt")

Defining networks

A TopologyNetwork is another object that is used for Topology creation, it defines one address pool, which interconnects all containers associated with it. When initializing networks, the following 3 main attributes are expected

  • Network mask is an integer in range 0 - 32

  • Network name is the identifier of the network for later use

  • Network IP address is a string in IPv4 address format 0-255.0-255.0-255.0-255 and identifies the network address, which is in combination with network mask also a pool of addresses for the network devices.

  • If the network serves as a corner gateway to the internet, the Internet attribute must be set to true.

Every router has a default gateway that targets the shortest path to internet network!

Initialization of Network object
import io.patriot_framework.network.simulator.api.model.network.TopologyNetwork;

TopologyNetwork tNet = new TopologyNetwork("Teacher", "192.168.0.0", 28);

For now, the entire topology is stored in TopologyNetwork objects. There is one more attribute named CalcRoutes that points to a list of CalcRoute objects. The list contains the description of topology (routes). Each CalcRoute object has 2 attributes:

  • NextHop object

    • Next hop router (object)

    • Next hop network position in the networks ArrayList (int)

  • Cost

    • If the networks are not directly connected, and have to be calculated, the cost must be equal to the networks ArrayList size + 1

    • If the target network is same as the source, the value of this attribute must be set to null in Java environments.

network
Figure 1. Schema

Comperhensive example

To show the Network Simulator in action, let’s assume the following scenario: we want to create the network topology that consists of three networks

  • First one is for teachers

  • Second one is for students

  • Third one is the backbone

  • And also we want to have a connection to the Internet

  • All parts of topology are for now created by docker, so we need to specify Docker as creator for whole topology

The following snippet shows basic objects that are needed for the simulation.

Create basic objects using TopologyBuilder
Topology topology = new TopologyBuilder(4)
                .withCreator("Docker")
                .withRouters()
                    .withName("TRt")
                    .createRouter()
                    .withName("SRt")
                    .createRouter()
                    .withName("MainRt")
                    .withCorner(true)
                    .createRouter()
                    .addRouters()
                .withNetwork("tNet")
                    .withIP("192.168.0.0")
                    .withMask(28)
                    .create()
                .withNetwork("sNet")
                    .withIP("192.168.16.0")
                    .withMask(28)
                    .create()
                .withNetwork("bNet")
                    .withIP("172.16.0.0")
                    .withMask(16)
                    .create()
                .withNetwork("iNet")
                    .withInternet(true)
                    .create()

After the base objects are defined, now it’s time to define the interconnection of the networks by putting the Routers in place. We have to specify route just one time, api will set same route in opposite direction (We specify tNet → bNet and api will set bNet → tNet too).

Set up the connection for Teacher network
int routNeedCalc = topology.getNetworks().size() + 1;
                .withRoutes()
                    .withSourceNetwork("tNet")
                    .withDestNetwork("sNet")
                    .viaRouter((RouterImpl)null)
                    .withCost(routNeedCalc)
                    .addRoute()
                    .withSourceNetwork("tNet")
                    .withDestNetwork("bNet")
                    .withCost(1)
                    .viaRouter("TRt")
                    .addRoute()
                    .withSourceNetwork("tNet")
                    .withDestNetwork("iNet")
                    .withCost(routNeedCalc)
                    .viaRouter((RouterImpl)null)
                    .addRoute
Set up the connection for Student network
                    .withSourceNetwork("sNet")
                    .withDestNetwork("bNet")
                    .withCost(1)
                    .viaRouter("SRt")
                    .addRoute()
                    .withSourceNetwork("sNet")
                    .withDestNetwork("iNet")
                    .withCost(routNeedCalc)
                    .viaRouter((RouterImpl)null)
                    .addRoute()
Set up connection for backbone network
                    .withSourceNetwork("bNet")
                    .withDestNetwork("iNet")
                    .withCost(1)
                    .viaRouter("MainR")
                    .buildRoute()
                    .buildRoutes()
                .build();

For iNet network we doesn’t have more routes to specify. After all of those commands are executed, our topology is ready to be deployed.

Deployment topology to environment

For deployment we need initialize Manager with 4 parameters:

  • List<Controller> controllers that will be used for environment creation

  • Patriot router image tag

Deployment of topology
Manager networkManager = PatriotHub.getInstance().getManager();
networkManager.setControllers(Arrays.asList(new DockerController()));
networkManager.deploy(topology);

Centralized logging

Central log server can be set with Manager attributes:

  • monitoringAddr - Logstash or Graylog ip address

  • monitoringPort - Logstash or Graylog port

If these parameters are set, all logs on stdout and stderr are logged into central server. Deployment of log server described in patriot-monitoring

Deployment of tested application

The last part of the Network Simulator is support for the deployment of a tested application into the simulated environment. In the current state the basic prerequisite is, that the application is containerized.

Deployment of an application into the simulated environment
    Manager networkManager = PatriotHub.getInstance().getManager();
    Topology topology = new TopologyBuilder(2)
                .withRouters()
                .withName("R1")
                .addRouters()
                .withNetwork("N1")
                    .withIP("192.168.0.0")
                    .withMask(28)
                .create()
                .withNetwork("N2")
                    .withIP("192.168.16.0")
                    .withMask(28)
                .create()
                .withRoutes()
                    .withSourceNetwork("N1")
                    .withDestNetwork("N2")
                    .withCost(1)
                    .viaRouter("R1")
                    .addRoute()
                .buildRoutes()
                .build();
        networkManager.setControllers(Arrays.asList(new DockerController());
        networkManager.deploy(topology);
        Application app = new Application("Generator", "Docker");
        networkManager.deployDeviceToNetwork(app,
        topology.getNetworks().get(1), topology, "app-1.0-SNAPSHOT");