Skip to content

Commit

Permalink
chore: IRouting interface
Browse files Browse the repository at this point in the history
  • Loading branch information
penglei0 committed Aug 4, 2024
1 parent 478a54d commit e44f1d4
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 80 deletions.
89 changes: 12 additions & 77 deletions src/containernet/containernet_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from containernet.topology import (ITopology, MatrixType)
from containernet.containernet_host import ContainernetHostAdapter
from interfaces.network import INetwork
from interfaces.routing import IRoutingStrategy
from .config import NodeConfig


Expand All @@ -30,9 +31,11 @@ class ContainerizedNetwork (INetwork):
def __init__(self,
node_config: NodeConfig = None,
net_topology: ITopology = None,
routing_strategy: IRoutingStrategy = None,
** params) -> None:
super().__init__(**params)
self.containernet = Containernet()
self.routing_strategy = routing_strategy
self.hosts = []
# NodeConfig: Docker node related
self.node_img = node_config.node_img
Expand Down Expand Up @@ -76,6 +79,9 @@ def __init__(self,
def get_hosts(self):
return self.hosts

def get_num_of_host(self):
return self.num_of_hosts

def start(self):
logging.info("Oasis starts the ContainerizedNetwork.")
self.containernet.build()
Expand Down Expand Up @@ -105,10 +111,13 @@ def reload(self, top: ITopology):
else:
self._shrink_network(diff)

def get_link_table(self):
return self.pair_to_link_ip

def _init_containernet(self):
self._setup_docker_nodes()
self._setup_topology()
self._setup_routes()
self.routing_strategy.setup_routes(self)

def _setup_docker_nodes(self):
"""
Expand Down Expand Up @@ -204,80 +213,6 @@ class 50001 is big. Consider r2q change.
port1, port2, cls=TCLink, **params)
return link

def _setup_routes(self):
if self.node_route == 'ip' and self.topology_type != 'linear':
logging.error(
"The ip routing config %s is not supported for %s.",
self.node_route, self.topology_type)
# setup routes
if self.node_route == 'ip':
self._setup_ip_routes()
elif self.node_route == 'olsr':
self._setup_olsr_routes()
else:
logging.error(
"The routing config %s is not supported.", self.node_route)

def _setup_ip_routes(self):
'''
Setup the routing by ip route.
'''
# need convert the node to "IHost" type: ContainernetHostAdapter(host)
for route in self.net_routes:
# route = [self.containernet.nameToNode[f'h{i}'] for i in route]
route = [self.hosts[i] for i in route]
self._add_route(route)

def _setup_olsr_routes(self):
'''
setup the OLSR routing
'''

@ staticmethod
def _add_ip_gateway(host, gateway_ip, dst_ip):
host.cmd(f'ip r a {dst_ip} via {gateway_ip}')

def _add_route(self, route):
for i in range(len(route) - 1):
for j in range(i + 1, len(route)):
host = route[i]
gateway = route[i + 1]
dst_prev = route[j - 1]
dst = route[j]
if j < len(route) - 1:
dst_next = route[j + 1]

# gateway ip is the ip of the second (right) interface
# of the link (route_i, route_{i+1})
gateway_ip = self.pair_to_link_ip[(host, gateway)]

# dst ip is the ip of the second (right) interface in the link
# (route_{j-1}, route_j)
dst_ip = self.pair_to_link_ip[(dst_prev, dst)]
if j < len(route) - 1:
dst_ip_right = self.pair_to_link_ip[(dst_next, dst)]
self._add_ip_gateway(host, gateway_ip, dst_ip)
if j < len(route) - 1:
self._add_ip_gateway(host, gateway_ip, dst_ip_right)

for i in range(1, len(route)):
for j in range(0, i):
host = route[i]
gateway = route[i - 1]
dst_prev = route[j + 1]
dst = route[j]

if j >= 1:
dst_next = route[j - 1]

gateway_ip = self.pair_to_link_ip[(host, gateway)]
dst_ip = self.pair_to_link_ip[(dst_prev, dst)]
if j >= 1:
dst_ip_left = self.pair_to_link_ip[(dst_next, dst)]
self._add_ip_gateway(host, gateway_ip, dst_ip)
if j >= 1:
self._add_ip_gateway(host, gateway_ip, dst_ip_left)

def _check_node_vols(self):
if not os.path.exists('/usr/bin/perf') or \
not os.path.isfile('/usr/bin/perf'):
Expand Down Expand Up @@ -308,7 +243,7 @@ def _expand_network(self, diff):
)
self.num_of_hosts += diff
self._setup_topology()
self._setup_routes()
self.routing_strategy.setup_routes(self)
logging.info(
"Expand the network. number of nodes increased by %s",
diff)
Expand All @@ -325,7 +260,7 @@ def _shrink_network(self, diff):
self.containernet.removeDocker(f'{self.node_name_prefix}{i}')
self.num_of_hosts -= diff
self._setup_topology()
self._setup_routes()
self.routing_strategy.setup_routes(self)
return True

def _reset_network(self, num, diff):
Expand Down
9 changes: 8 additions & 1 deletion src/interfaces/network.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import logging
from typing import List
from abc import ABC, abstractmethod
from containernet.topology import (ITopology)
from testsuites.test import ITestSuite
Expand All @@ -21,6 +20,14 @@ def stop(self):
def get_hosts(self):
pass

@abstractmethod
def get_num_of_host(self):
pass

@abstractmethod
def get_link_table(self):
pass

@abstractmethod
def reload(self, top: ITopology):
pass
Expand Down
6 changes: 6 additions & 0 deletions src/interfaces/routing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from abc import ABC, abstractmethod

class IRoutingStrategy(ABC):
@abstractmethod
def setup_routes(self, network):
pass
9 changes: 9 additions & 0 deletions src/routing/olsr_routing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from interfaces.routing import IRoutingStrategy

class OLSRRouting(IRoutingStrategy):
"""Summary:
Configure routing for the network with OLSR.
"""
def setup_routes(self, network: 'INetwork'): # type: ignore
pass

9 changes: 9 additions & 0 deletions src/routing/openr_routing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from interfaces.routing import IRoutingStrategy

class OpenrRouting(IRoutingStrategy):
"""Summary:
Configure routing for the network with open-r.
"""
def setup_routes(self, network: 'INetwork'): # type: ignore
pass

65 changes: 65 additions & 0 deletions src/routing/static_routing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from interfaces.routing import IRoutingStrategy

class StaticRouting(IRoutingStrategy):
"""Summary:
Configure static routing for the network.
"""
def __init__(self):
self.pair_to_link_ip = {}
self.net_routes = []

def setup_routes(self, network: 'INetwork'):
'''
Setup the routing by ip route.
'''
hosts = network.get_hosts()
self.pair_to_link_ip = network.get_link_table()
self.net_routes = [range(network.get_num_of_host())]
for route in self.net_routes:
route = [hosts[i] for i in route]
self._add_route(route)

@ staticmethod
def _add_ip_gateway(host, gateway_ip, dst_ip):
host.cmd(f'ip r a {dst_ip} via {gateway_ip}')

def _add_route(self, route):
for i in range(len(route) - 1):
for j in range(i + 1, len(route)):
host = route[i]
gateway = route[i + 1]
dst_prev = route[j - 1]
dst = route[j]
if j < len(route) - 1:
dst_next = route[j + 1]

# gateway ip is the ip of the second (right) interface
# of the link (route_i, route_{i+1})
gateway_ip = self.pair_to_link_ip[(host, gateway)]

# dst ip is the ip of the second (right) interface in the link
# (route_{j-1}, route_j)
dst_ip = self.pair_to_link_ip[(dst_prev, dst)]
if j < len(route) - 1:
dst_ip_right = self.pair_to_link_ip[(dst_next, dst)]
self._add_ip_gateway(host, gateway_ip, dst_ip)
if j < len(route) - 1:
self._add_ip_gateway(host, gateway_ip, dst_ip_right)

for i in range(1, len(route)):
for j in range(0, i):
host = route[i]
gateway = route[i - 1]
dst_prev = route[j + 1]
dst = route[j]

if j >= 1:
dst_next = route[j - 1]

gateway_ip = self.pair_to_link_ip[(host, gateway)]
dst_ip = self.pair_to_link_ip[(dst_prev, dst)]
if j >= 1:
dst_ip_left = self.pair_to_link_ip[(dst_next, dst)]
self._add_ip_gateway(host, gateway_ip, dst_ip)
if j >= 1:
self._add_ip_gateway(host, gateway_ip, dst_ip_left)
4 changes: 2 additions & 2 deletions src/run_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from testsuites.test import (TestType, TestConfig)
from testsuites.test_iperf import IperfTest
from testsuites.test_ping import PingTest

from routing.static_routing import StaticRouting

def load_test(test_yaml_file: str):
"""
Expand Down Expand Up @@ -95,7 +95,7 @@ def build_network(node_config: NodeConfig, top_config: TopologyConfig):
ContainerizedNetwork: the container network object
"""
net_top = build_topology(top_config)
return ContainerizedNetwork(node_config, net_top)
return ContainerizedNetwork(node_config, net_top, StaticRouting())


if __name__ == '__main__':
Expand Down

0 comments on commit e44f1d4

Please sign in to comment.