Network Emulation Example#
Wattson allows you to create your emulated network from scratch. Please not that you have to run python as super user (e.g., with sudo) since the creation of network namespaces and interfaces requires these privileges.
In case anything goes wrong or crashes, remember to run
sudo python3 -m wattson.util.clean
to clean up any remains of the network emulation.
Example Code#
This example code creates a simple network, consisting of two hosts connected via a switch and a router. After the simulation is started, you will be dropped to a CLI to interact with the network, open terminals for the hosts, or further manipulate the active simulation.
Save the contents to the file network_example.py
and run
sudo python3 network_example.py
Contents for the network_example.py
from pathlib import Path
from wattson.cosimulation.control.co_simulation_controller import CoSimulationController
from wattson.cosimulation.simulators.network.emulators.wattson_network_emulator import WattsonNetworkEmulator
from wattson.cosimulation.simulators.physical.empty_physical_simulator import EmptyPhysicalSimulator
from wattson.cosimulation.simulators.network.components.wattson_network_host import WattsonNetworkHost
from wattson.cosimulation.simulators.network.components.wattson_network_router import WattsonNetworkRouter
from wattson.cosimulation.simulators.network.components.wattson_network_docker_router import WattsonNetworkDockerRouter
from wattson.cosimulation.simulators.network.components.wattson_network_switch import WattsonNetworkSwitch
# Use the empty simulator when no power grid simulation in required
physical_simulator = EmptyPhysicalSimulator()
# The WattsonNetworkEmulator allows to create and emulate your desired network
network_emulator = WattsonNetworkEmulator()
# The management of the (co-)simulation is done by the CoSimulationController
# It allows you to create a manual scenario based on the created simulators
# It takes a working directory as argument.
controller = CoSimulationController(Path("network-example"))
controller.manual_scenario(network_emulator=network_emulator, physical_simulator=physical_simulator)
# We can now build our simple network, consisting of two hosts, one switch, and one router:
# Host 1 --- Router --- Switch --- Host 2
host1 = WattsonNetworkHost(id="host1")
host2 = WattsonNetworkHost(id="host2")
switch1 = WattsonNetworkSwitch(id="switch1")
router1 = WattsonNetworkRouter(id="router1")
# You can also use a docker-based router instead
#router = WattsonNetworkDockerRouter(id="router1", config={"image": "wattson-router"})
# Specify IP adresses to use
h1_ip = "172.16.1.10"
h2_ip = "172.16.2.20"
r1_ip_a = "172.16.1.1"
r1_ip_b = "172.16.2.1"
# Add them to the network emulator and set up their connections
network_emulator.add_host(host1)
network_emulator.add_host(host2)
network_emulator.add_router(router1)
network_emulator.add_switch(switch1)
# Here, you can set interface IPs and link properties
# Wattson provides helper methods to allow the network setup.
# For advanced scenarios, you can always manually create interfaces and links.
## We connect node_a=host1 with node_b=router1.
## We can provide options such as the IP address for the created interfaces as well as options for the link.
network_emulator.connect_nodes(
host1,
router1,
interface_a_options={"ip": h1_ip, "prefix_length": 24},
interface_b_options={"ip": r1_ip_a, "prefix_length": 24},
link_options={"config": {"delay": "10ms", "bandwidth": "10mbps"}}
)
network_emulator.connect_nodes(
host2,
switch1,
interface_a_options={"ip": h2_ip, "prefix_length": 24},
link_options={"config": {"delay": "10ms", "bandwidth": "10mbps"}}
)
network_emulator.connect_nodes(
switch1,
router1,
interface_b_options={"ip": r1_ip_b, "prefix_length": 24},
link_options={"config": {"delay": "10ms", "bandwidth": "10mbps"}}
)
# Now we can run the emulation
controller.start()
# This drops to a command line interface that blocks until the simulation is stopped.
# You can type "exit" to exit the CLI and shut the simulation down
controller.cli()
# Finally, the simulation is stopped and cleaned up.
controller.stop()