diff --git a/config/topo/topo_cong b/config/topo/topo_cong new file mode 100644 index 0000000..068b51c --- /dev/null +++ b/config/topo/topo_cong @@ -0,0 +1,5 @@ +leftSubnet:10.0. +rightSubnet:10.1. +path_c2r_0:10,10,4 +path_c2r_1:40,30,4 +topoType:MultiIfMultiClient diff --git a/experiments/iperf_scenario.py b/experiments/iperf_scenario.py new file mode 100644 index 0000000..9a275dc --- /dev/null +++ b/experiments/iperf_scenario.py @@ -0,0 +1,60 @@ +from core.experiment import Experiment, ExperimentParameter +from topos.multi_interface_multi_client import MultiInterfaceMultiClientTopo +import logging +import os + + +class IPerfScenario(Experiment): + NAME = "iperfScenario" + + IPERF_LOG = "iperf.log" + SERVER_LOG = "server.log" + IPERF_BIN = "iperf3" + PING_OUTPUT = "ping.log" + + def __init__(self, experiment_parameter_filename, topo, topo_config): + super(IPerfScenario, self).__init__(experiment_parameter_filename, topo, topo_config) + self.load_parameters() + self.ping() + + def prepare(self): + super(IPerfScenario, self).prepare() + self.topo.command_to(self.topo_config.client, "rm {}".format(IPerfScenario.IPERF_LOG)) + self.topo.command_to(self.topo_config.server, "rm {}".format(IPerfScenario.SERVER_LOG)) + + if not isinstance(self.topo, MultiInterfaceMultiClientTopo): + raise Exception("IPerfScenario only runs with MultiInterfaceMultiClientTopo") + + def get_client_iperf_cmd(self, server_ip, time, client_id): + s = "{} -c {} -t {} -P 1 &>{}{}".format(IPerfScenario.IPERF_BIN, server_ip, time, IPerfScenario.IPERF_LOG, client_id) + logging.info(s) + return s + + def get_server_cmd(self, server_id=0): + s = "{} -s &> {}{} &".format(IPerfScenario.IPERF_BIN, IPerfScenario.SERVER_LOG, server_id) + logging.info(s) + return s + + def clean(self): + super(IPerfScenario, self).clean() + + def run(self): + # First run servers + for l, s in enumerate(self.topo_config.servers): + self.topo.command_to(s, self.get_server_cmd(server_id=l)) + + # Disable MPTCP on all congestion clients + for c in self.topo_config.clients[1:]: + self.topo.command_to(c, "sysctl -w net.mptcp.mptcp_enabled=0") + + self.topo.command_to(self.topo_config.client, "sleep 2") + + # We run as follow. + logging.info("This experiment last about 1 minute. Please wait...") + cmd = "sleep 10 && {} &".format(self.get_client_iperf_cmd(self.topo_config.get_server_ip(interface_index=1), 20, 1)) + self.topo.command_to(self.topo_config.clients[1], cmd) + cmd = "sleep 20 && {} &".format(self.get_client_iperf_cmd(self.topo_config.get_server_ip(interface_index=2), 20, 2)) + self.topo.command_to(self.topo_config.clients[2], cmd) + cmd = self.get_client_iperf_cmd(self.topo_config.get_server_ip(), 50, 0) + self.topo.command_to(self.topo_config.client, cmd) + self.topo.command_to(self.topo_config.client, "sleep 2") diff --git a/experiments/quic.py b/experiments/quic.py index d97bcba..69080fd 100644 --- a/experiments/quic.py +++ b/experiments/quic.py @@ -1,5 +1,5 @@ from core.experiment import RandomFileExperiment, RandomFileParameter, ExperimentParameter -from topos.multi_interface_cong import MultiInterfaceCongConfig +from topos.multi_interface_multi_client import MultiInterfaceMultiClientConfig import os @@ -91,7 +91,7 @@ class QUIC(RandomFileExperiment): self.topo.command_to(self.topo_config.server, "netstat -sn > netstat_server_before") self.topo.command_to(self.topo_config.server, cmd) - if isinstance(self.topo_config, MultiInterfaceCongConfig): + if isinstance(self.topo_config, MultiInterfaceMultiClientConfig): i = 0 for cs in self.topo_config.cong_servers: cmd = self.getCongServerCmd(i) @@ -102,7 +102,7 @@ class QUIC(RandomFileExperiment): self.topo.command_to(self.topo_config.client, "netstat -sn > netstat_client_before") # First run congestion clients, then the main one - if isinstance(self.topo_config, MultiInterfaceCongConfig): + if isinstance(self.topo_config, MultiInterfaceMultiClientConfig): i = 0 for cc in self.topo_config.cong_clients: cmd = self.getCongClientCmd(i) @@ -114,12 +114,12 @@ class QUIC(RandomFileExperiment): self.topo.command_to(self.topo_config.server, "netstat -sn > netstat_server_after") self.topo.command_to(self.topo_config.client, "netstat -sn > netstat_client_after") # Wait for congestion traffic to end - if isinstance(self.topo_config, MultiInterfaceCongConfig): + if isinstance(self.topo_config, MultiInterfaceMultiClientConfig): for cc in self.topo_config.cong_clients: self.topo.command_to(cc, "while pkill -f wget -0; do sleep 0.5; done") self.topo.command_to(self.topo_config.server, "pkill -f " + QUIC.SERVER_GO_FILE) - if isinstance(self.topo_config, MultiInterfaceCongConfig): + if isinstance(self.topo_config, MultiInterfaceMultiClientConfig): for cs in self.topo_config.cong_servers: self.topo.command_to(cs, "pkill -f https_server.py") diff --git a/topos/ecmp_single_interface.py b/topos/ecmp_single_interface.py deleted file mode 100644 index 40f2105..0000000 --- a/topos/ecmp_single_interface.py +++ /dev/null @@ -1,206 +0,0 @@ -from core.topo import Topo, TopoConfig, TopoParameter -from struct import * - -class ECMPSingleInterfaceTopo(Topo): - NAME = "ECMPLike" - - def __init__(self, topo_builder, parameterFile): - raise Exception("Broken") - super(ECMPSingleInterfaceTopo, self).__init__(topo_builder, parameterFile) - - print("Hello ECMP topo") - - self.client = self.add_host(Topo.CLIENT_NAME) - self.server = self.add_host(Topo.SERVER_NAME) - self.lswitch = self.add_switch(Topo.SWITCH_NAME_PREFIX + "0") - self.rswitch = self.add_switch(Topo.SWITCH_NAME_PREFIX + "1") - - self.add_link( self.client, self.lswitch) - self.add_link( self.server, self.rswitch) - - self.routers = [] - for l in self.topo_parameter.link_characteristics: - self.routers.append(self.addOneRouterPerLink(l)) - print("added : " + self.routers[-1]) - self.add_link(self.lswitch, self.routers[-1]) - self.add_link(self.rswitch, self.routers[-1], **l.as_dict()) - - def addOneRouterPerLink(self, link): - return self.add_host(Topo.ROUTER_NAME_PREFIX + - str(link.id)) - - def __str__(self): - s = "Single if ECMP like env\n" - i = 0 - n = len(self.topo_parameter.link_characteristics) - for p in self.topo_parameter.link_characteristics: - if i == n // 2: - if n % 2 == 0: - s = s + "c---sw sw-----s\n" - s = s + " |-----R-----|\n" - else: - s = s + "c---sw----R-----sw-----s\n" - else: - s = s + " |-----R-----|\n" - - i = i + 1 - return s - - -class ECMPSingleInterfaceConfig(TopoConfig): - NAME = "ECMPLike" - - def __init__(self, topo, param): - super(ECMPSingleInterfaceConfig, self).__init__(topo, param) - - def configure_routing(self): - i = 0 - mask = len(self.topo.routers) - 1 - for l in self.topo.routers: - cmd = self.getIptableRuleICMP(mask, i) - self.topo.command_to(self.client, cmd) - self.topo.command_to(self.server, cmd) - - cmd = self.getIptableRuleTCPPortClient(mask, i) - self.topo.command_to(self.client, cmd) - cmd = self.getIptableRuleTCPPortServer(mask, i) - self.topo.command_to(self.server, cmd) - - cmd = self.getIpRuleCmd(i) - self.topo.command_to(self.client, cmd) - self.topo.command_to(self.server, cmd) - - cmd = self.getDefaultRouteCmd(self.getRouterIPClient(i), - i) - self.topo.command_to(self.client, cmd) - cmd = self.getDefaultRouteCmd(self.getRouterIPServer(i), - i) - self.topo.command_to(self.server, cmd) - - i = i + 1 - - ### - cmd = self.add_simple_default_route_command(self.getRouterIPServer(0)) - self.topo.command_to(self.server, cmd) - - cmd = self.add_simple_default_route_command(self.getRouterIPClient(0)) - self.topo.command_to(self.client, cmd) - - self.topo.command_to(self.client, "ip route flush cache") - self.topo.command_to(self.server, "ip route flush cache") - - def getIptableRuleICMP(self, mask, id): - s = 'iptables -t mangle -A OUTPUT -m u32 --u32 ' + \ - '"6&0xFF=0x1 && ' + \ - '24&0x' + \ - pack('>I',(mask)).encode('hex') + \ - '=0x' + pack('>I',id).encode('hex') + \ - '" -j MARK --set-mark ' + str(id + 1) - print (s) - return s - - def getIptableRuleTCPPortClient(self, mask, id): - s = 'iptables -t mangle -A OUTPUT -m u32 --u32 ' + \ - '"6&0xFF=0x6 && ' + \ - '18&0x' + \ - pack('>I',(mask)).encode('hex') + \ - '=0x' + pack('>I',id).encode('hex') + \ - '" -j MARK --set-mark ' + str(id + 1) - print (s) - return s - - def getIptableRuleTCPPortServer(self, mask, id): - s = 'iptables -t mangle -A OUTPUT -m u32 --u32 ' + \ - '"6&0xFF=0x6 && ' + \ - '20&0x' + \ - pack('>I',(mask)).encode('hex') + \ - '=0x' + pack('>I',id).encode('hex') + \ - '" -j MARK --set-mark ' + str(id + 1) - print (s) - return s - - def getIpRuleCmd(self, id): - s = 'ip rule add fwmark ' + str(id + 1) + ' table ' + \ - str(id + 1) - print(s) - return s - - def getDefaultRouteCmd(self, via, id): - s = 'ip route add default via ' + via + ' table ' + str(id + 1) - print(s) - return s - - def configure_interfaces(self): - self.client = self.topo.get_host(Topo.CLIENT_NAME) - self.server = self.topo.get_host(Topo.SERVER_NAME) - self.routers = [] - i = 0 - netmask = "255.255.255.0" - for l in self.topo.routers: - self.routers.append(self.topo.get_host( - Topo.ROUTER_NAME_PREFIX + str(i))) - cmd = self.interface_up_command( - self.getRouterInterfaceLSwitch(i), - self.getRouterIPClient(i), netmask) - self.topo.command_to(self.routers[-1] , cmd) - - cmd = self.interface_up_command( - self.getRouterInterfaceRSwitch(i), - self.getRouterIPServer(i), netmask) - self.topo.command_to(self.routers[-1] , cmd) - - i = i + 1 - - cmd = self.interface_up_command(self.get_client_interface(0), - self.get_client_ip(0), netmask) - self.topo.command_to(self.client, cmd) - - cmd = self.interface_up_command(self.get_server_interface(), - self.get_server_ip(), netmask) - self.topo.command_to(self.server, cmd) - - def get_client_ip(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - clientIP = lSubnet + str(interfaceID) + ".1" - return clientIP - - def getClientSubnet(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - clientSubnet = lSubnet + str(interfaceID) + ".0/24" - return clientSubnet - - def getRouterIPClient(self, id): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - routerIP = lSubnet + "0." + str(id + 2) - return routerIP - - def getRouterIPServer(self, id): - rSubnet = self.param.get(TopoParameter.RIGHT_SUBNET) - routerIP = rSubnet + "0." + str(id + 2) - return routerIP - - def get_server_ip(self): - rSubnet = self.param.get(TopoParameter.RIGHT_SUBNET) - serverIP = rSubnet + "0.1" - return serverIP - - def client_interface_count(self): - return 1 - - def getRouterInterfaceLSwitch(self, id): - return Topo.ROUTER_NAME_PREFIX + str(id) + "-eth0" - - def getRouterInterfaceRSwitch(self, id): - return Topo.ROUTER_NAME_PREFIX + str(id) + "-eth1" - - def get_client_interface(self, interfaceID): - return Topo.CLIENT_NAME + "-eth" + str(interfaceID) - - def get_server_interface(self): - return Topo.SERVER_NAME + "-eth0" - - def getMidLeftName(self, id): - return Topo.ROUTER_NAME_PREFIX + str(id) - - def getMidRightName(self, id): - return Topo.SWITCH_NAME_PREFIX + "1" diff --git a/topos/multi_interface_cong.py b/topos/multi_interface_cong.py deleted file mode 100644 index 79bcc5b..0000000 --- a/topos/multi_interface_cong.py +++ /dev/null @@ -1,267 +0,0 @@ -from core.topo import TopoConfig, Topo, TopoParameter - - -class MultiInterfaceCongTopo(Topo): - NAME = "MultiIfCong" - - congClientName = "CCli" - congServerName = "CSer" - - def __init__(self, topo_builder, parameterFile): - raise Exception("Broken") - super(MultiInterfaceCongTopo, self).__init__(topo_builder, parameterFile) - print("Hello from topo multi if") - self.client = self.add_host(Topo.CLIENT_NAME) - self.server = self.add_host(Topo.SERVER_NAME) - self.router = self.add_host(Topo.ROUTER_NAME) - self.cong_clients = [] - self.cong_servers = [] - self.switch = [] - for l in self.topo_parameter.link_characteristics: - self.switch.append(self.addOneSwitchPerLink(l)) - self.add_link(self.client,self.switch[-1]) - self.cong_clients.append(self.add_host(MultiInterfaceCongTopo.congClientName + str(len(self.cong_clients)))) - self.add_link(self.cong_clients[-1], self.switch[-1]) - self.add_link(self.switch[-1],self.router, **l.as_dict()) - self.add_link(self.router, self.server) - for i in range(len(self.cong_clients)): - self.cong_servers.append(self.add_host(MultiInterfaceCongTopo.congServerName + str(len(self.cong_servers)))) - self.add_link(self.router, self.cong_servers[-1]) - - def getCongClients(self): - return self.cong_clients - - def getCongServers(self): - return self.cong_servers - - def addOneSwitchPerLink(self, link): - return self.add_switch(MultiInterfaceCongTopo.SWITCH_NAME_PREFIX + - str(link.id)) - - def __str__(self): - s = "Simple multiple interface topology with congestion \n" - i = 0 - n = len(self.topo_parameter.link_characteristics) - for p in self.topo_parameter.link_characteristics: - if i == n // 2: - if n % 2 == 0: - s = s + "c r-----s\n" - s = s + "|-----sw-----|\n" - else: - s = s + "c-----sw-----r-----s\n" - else: - s = s + "|-----sw-----|\n" - - i = i + 1 - return s - - -class MultiInterfaceCongConfig(TopoConfig): - NAME = "MultiIfCong" - - def __init__(self, topo, param): - super(MultiInterfaceCongConfig, self).__init__(topo, param) - - def configure_routing(self): - i = 0 - for l in self.topo.switch: - cmd = self.add_table_route_command(self.get_client_ip(i), i) - self.topo.command_to(self.client, cmd) - - # Congestion client - cmd = self.add_table_route_command(self.getCongClientIP(i), i) - self.topo.command_to(self.cong_clients[i], cmd) - - cmd = self.add_link_scope_route_command( - self.getClientSubnet(i), - self.get_client_interface(i), i) - self.topo.command_to(self.client, cmd) - - # Congestion client - cmd = self.add_link_scope_route_command( - self.getClientSubnet(i), - self.getCongClientInterface(i), i) - self.topo.command_to(self.cong_clients[i], cmd) - - cmd = self.add_table_default_route_command(self.getRouterIPSwitch(i), - i) - self.topo.command_to(self.client, cmd) - - # Congestion client - # Keep the same command - self.topo.command_to(self.cong_clients[i], cmd) - - # Congestion client - cmd = self.add_global_default_route_command(self.getRouterIPSwitch(i), - self.getCongClientInterface(i)) - i = i + 1 - - cmd = self.add_global_default_route_command(self.getRouterIPSwitch(0), - self.get_client_interface(0)) - self.topo.command_to(self.client, cmd) - - # Congestion Client - i = 0 - for c in self.cong_clients: - cmd = self.add_global_default_route_command(self.getRouterIPSwitch(i), - self.getCongClientInterface(i)) - self.topo.command_to(c, cmd) - i = i + 1 - - cmd = self.add_simple_default_route_command(self.getRouterIPServer()) - self.topo.command_to(self.server, cmd) - # Congestion servers - i = 0 - for s in self.cong_servers: - cmd = self.add_simple_default_route_command(self.getRouterIPCongServer(i)) - self.topo.command_to(s, cmd) - i += 1 - - - def configure_interfaces(self): - print("Configure interfaces for multi inf") - self.client = self.topo.get_host(Topo.CLIENT_NAME) - self.server = self.topo.get_host(Topo.SERVER_NAME) - self.router = self.topo.get_host(Topo.ROUTER_NAME) - cong_client_names = self.topo.getCongClients() - self.cong_clients = [] - for cn in cong_client_names: - self.cong_clients.append(self.topo.get_host(cn)) - - cong_server_names = self.topo.getCongServers() - self.cong_servers = [] - for sn in cong_server_names: - self.cong_servers.append(self.topo.get_host(sn)) - - i = 0 - netmask = "255.255.255.0" - links = self.topo.get_link_characteristics() - for l in self.topo.switch: - cmd = self.interface_up_command( - self.get_client_interface(i), - self.get_client_ip(i), netmask) - self.topo.command_to(self.client, cmd) - clientIntfMac = self.client.intf(self.get_client_interface(i)).MAC() - self.topo.command_to(self.router, "arp -s " + self.get_client_ip(i) + " " + clientIntfMac) - - if(links[i].backup): - cmd = self.interface_backup_command( - self.get_client_interface(i)) - self.topo.command_to(self.client, cmd) - - # Congestion client - cmd = self.interface_up_command( - self.getCongClientInterface(i), - self.getCongClientIP(i), netmask) - self.topo.command_to(self.cong_clients[i], cmd) - congClientIntfMac = self.cong_clients[i].intf(self.getCongClientInterface(i)).MAC() - self.topo.command_to(self.router, "arp -s " + self.getCongClientIP(i) + " " + congClientIntfMac) - - cmd = self.interface_up_command( - self.get_router_interface_to_client_switch(i), - self.getRouterIPSwitch(i), netmask) - self.topo.command_to(self.router, cmd) - routerIntfMac = self.router.intf(self.get_router_interface_to_client_switch(i)).MAC() - self.topo.command_to(self.client, "arp -s " + self.getRouterIPSwitch(i) + " " + routerIntfMac) - # Don't forget the congestion client - self.topo.command_to(self.cong_clients[i], "arp -s " + self.getRouterIPSwitch(i) + " " + routerIntfMac) - print(str(links[i])) - i = i + 1 - - cmd = self.interface_up_command(self.get_router_interface_to_server(), - self.getRouterIPServer(), netmask) - self.topo.command_to(self.router, cmd) - routerIntfMac = self.router.intf(self.get_router_interface_to_server()).MAC() - self.topo.command_to(self.server, "arp -s " + self.getRouterIPServer() + " " + routerIntfMac) - - cmd = self.interface_up_command(self.get_server_interface(), - self.get_server_ip(), netmask) - self.topo.command_to(self.server, cmd) - serverIntfMac = self.server.intf(self.get_server_interface()).MAC() - self.topo.command_to(self.router, "arp -s " + self.get_server_ip() + " " + serverIntfMac) - - # Congestion servers - i = 0 - for s in self.cong_servers: - cmd = self.interface_up_command(self.getRouterInterfaceCongServer(i), - self.getRouterIPCongServer(i), netmask) - self.topo.command_to(self.router, cmd) - routerIntfMac = self.router.intf(self.getRouterInterfaceCongServer(i)).MAC() - self.topo.command_to(s, "arp -s " + self.getRouterIPCongServer(i) + " " + routerIntfMac) - - cmd = self.interface_up_command(self.getCongServerInterface(i), - self.getCongServerIP(i), netmask) - self.topo.command_to(s, cmd) - congServerIntfMac = s.intf(self.getCongServerInterface(i)).MAC() - self.topo.command_to(self.router, "arp -s " + self.getCongServerIP(i) + " " + congServerIntfMac) - i = i + 1 - - def get_client_ip(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - clientIP = lSubnet + str(interfaceID) + ".1" - return clientIP - - def getCongClientIP(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - congClientIP = lSubnet + str(interfaceID) + ".127" - return congClientIP - - def getClientSubnet(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - clientSubnet = lSubnet + str(interfaceID) + ".0/24" - return clientSubnet - - def getRouterIPSwitch(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - routerIP = lSubnet + str(interfaceID) + ".2" - return routerIP - - def getRouterIPServer(self): - rSubnet = self.param.get(TopoParameter.RIGHT_SUBNET) - routerIP = rSubnet + "0.2" - return routerIP - - def getRouterIPCongServer(self, congID): - rSubnet = self.param.get(TopoParameter.RIGHT_SUBNET) - routerIP = rSubnet + str(1 + congID) + ".2" - return routerIP - - def get_server_ip(self): - rSubnet = self.param.get(TopoParameter.RIGHT_SUBNET) - serverIP = rSubnet + "0.1" - return serverIP - - def getCongServerIP(self, congID): - rSubnet = self.param.get(TopoParameter.RIGHT_SUBNET) - serverIP = rSubnet + str(1 + congID) + ".1" - return serverIP - - def client_interface_count(self): - return len(self.topo.switch) - - def get_router_interface_to_server(self): - return self.get_router_interface_to_client_switch(len(self.topo.switch)) - - def getRouterInterfaceCongServer(self, congID): - return self.get_router_interface_to_client_switch(len(self.topo.switch) + 1 + congID) - - def get_client_interface(self, interfaceID): - return Topo.CLIENT_NAME + "-eth" + str(interfaceID) - - def getCongClientInterface(self, interfaceID): - return MultiInterfaceCongConfig.congClientName + str(interfaceID) + "-eth0" - - def get_router_interface_to_client_switch(self, interfaceID): - return Topo.ROUTER_NAME + "-eth" + str(interfaceID) - - def get_server_interface(self): - return Topo.SERVER_NAME + "-eth0" - - def getCongServerInterface(self, interfaceID): - return MultiInterfaceCongConfig.congServerName + str(interfaceID) + "-eth0" - - def getMidLeftName(self, id): - return Topo.SWITCH_NAME_PREFIX + str(id) - - def getMidRightName(self, id): - return Topo.ROUTER_NAME \ No newline at end of file diff --git a/topos/multi_interface_multi_client.py b/topos/multi_interface_multi_client.py new file mode 100644 index 0000000..7358848 --- /dev/null +++ b/topos/multi_interface_multi_client.py @@ -0,0 +1,178 @@ +from core.topo import Topo, TopoConfig, TopoParameter +import logging + + +class MultiInterfaceMultiClientTopo(Topo): + NAME = "MultiIfMultiClient" + + def __init__(self, topo_builder, parameterFile): + logging.info("Initializing MultiInterfaceTopo...") + super(MultiInterfaceMultiClientTopo, self).__init__(topo_builder, parameterFile) + self.router = self.add_router() + self.c2r_client_switches = [] + self.c2r_router_switches = [] + + # First add the base client and server + self.client = self.add_client() + self.server = self.add_server() + + # For each client-router, add a client, a bottleneck link, and a server + for l in self.get_client_to_router_links(): + client = self.add_client() + server = self.add_server() + self.c2r_client_switches.append(self.add_c2r_client_side_switch(l)) + self.add_link(self.client, self.c2r_client_switches[-1]) + self.add_link(client, self.c2r_client_switches[-1]) + self.c2r_router_switches.append(self.add_c2r_router_side_switch(l)) + self.add_bottleneck_link(self.c2r_client_switches[-1], self.c2r_router_switches[-1], link_characteristics=l) + self.add_link(self.c2r_router_switches[-1], self.router) + + # And connect the router to all servers + for s in self.servers: + self.add_link(self.router, s) + + def get_client_to_router_links(self): + return [l for l in self.topo_parameter.link_characteristics if l.link_type == "c2r"] + + def add_c2r_client_side_switch(self, link): + return self.add_switch("{}c2r{}".format(MultiInterfaceMultiClientTopo.SWITCH_NAME_PREFIX, 2 * link.id)) + + def add_c2r_router_side_switch(self, link): + return self.add_switch("{}c2r{}".format(MultiInterfaceMultiClientTopo.SWITCH_NAME_PREFIX, 2 * link.id + 1)) + + def __str__(self): + s = "Multiple interface topology with several clients and servers\n" + i = 0 + nc = len(self.get_client_to_router_links()) + for i in range(0, nc): + if i == nc // 2: + s = s + "c- r--s\n" + s = s + "c-\sw---bl---sw-/ \-s\n" + else: + s = s + "c-/sw---bl---sw-\ /-s\n" + + return s + + +class MultiInterfaceMultiClientConfig(TopoConfig): + NAME = "MultiIfMultiClient" + + def __init__(self, topo, param): + super(MultiInterfaceMultiClientConfig, self).__init__(topo, param) + + def configure_routing(self): + for i, l in enumerate(self.topo.c2r_client_switches): + # Routing for the core client + cmd = self.add_table_route_command(self.get_client_ip(i), i) + self.topo.command_to(self.client, cmd) + + cmd = self.add_link_scope_route_command( + self.get_client_subnet(i), + self.get_client_interface(0, i), i) + self.topo.command_to(self.client, cmd) + + cmd = self.add_table_default_route_command(self.get_router_ip_to_client_switch(i), + i) + self.topo.command_to(self.client, cmd) + + # Routing for the congestion client + cmd = self.add_global_default_route_command(self.get_router_ip_to_client_switch(i), + self.get_client_interface(i+1, 0)) + self.topo.command_to(self.clients[i+1], cmd) + + cmd = self.add_global_default_route_command(self.get_router_ip_to_client_switch(0), + self.get_client_interface(0, 0)) + self.topo.command_to(self.client, cmd) + + for i, s in enumerate(self.topo.servers): + cmd = self.add_simple_default_route_command(self.get_router_ip_to_server_switch(i)) + self.topo.command_to(s, cmd) + + def configure_interfaces(self): + logging.info("Configure interfaces using MultiInterfaceMultiClientConfig...") + super(MultiInterfaceMultiClientConfig, self).configure_interfaces() + self.clients = [self.topo.get_client(i) for i in range(0, self.topo.client_count())] + self.servers = [self.topo.get_server(i) for i in range(0, self.topo.server_count())] + self.client = self.clients[0] + self.server = self.servers[0] + self.router = self.topo.get_router(0) + netmask = "255.255.255.0" + + for i, l in enumerate(self.topo.c2r_client_switches): + # Core client + cmd = self.interface_up_command(self.get_client_interface(0, i), self.get_client_ip(i), netmask) + self.topo.command_to(self.client, cmd) + client_interface_mac = self.client.intf(self.get_client_interface(0, i)).MAC() + self.topo.command_to(self.router, "arp -s {} {}".format(self.get_client_ip(i), client_interface_mac)) + + if self.topo.get_client_to_router_links()[i].backup: + cmd = self.interface_backup_command(self.get_client_interface(0, i)) + self.topo.command_to(self.client, cmd) + + # Congestion client + cmd = self.interface_up_command(self.get_client_interface(i + 1, 0), self.get_client_ip(i, congestion_client=True), netmask) + self.topo.command_to(self.clients[i+1], cmd) + client_interface_mac = self.clients[i+1].intf(self.get_client_interface(i + 1, 0)).MAC() + self.topo.command_to(self.router, "arp -s {} {}".format(self.get_client_ip(i, congestion_client=True), client_interface_mac)) + + for i, l in enumerate(self.topo.c2r_router_switches): + cmd = self.interface_up_command(self.get_router_interface_to_client_switch(i), + self.get_router_ip_to_client_switch(i), netmask) + self.topo.command_to(self.router, cmd) + + router_interface_mac = self.router.intf(self.get_router_interface_to_client_switch(i)).MAC() + # Core client + self.topo.command_to(self.client, "arp -s {} {}".format( + self.get_router_ip_to_client_switch(i), router_interface_mac)) + # Congestion client + self.topo.command_to(self.clients[i+1], "arp -s {} {}".format( + self.get_router_ip_to_client_switch(i), router_interface_mac)) + + for i, s in enumerate(self.servers): + cmd = self.interface_up_command(self.get_router_interface_to_server_switch(i), + self.get_router_ip_to_server_switch(i), netmask) + self.topo.command_to(self.router, cmd) + router_interface_mac = self.router.intf(self.get_router_interface_to_server_switch(i)).MAC() + self.topo.command_to(s, "arp -s {} {}".format( + self.get_router_ip_to_server_switch(i), router_interface_mac)) + cmd = self.interface_up_command(self.get_server_interface(i, 0), self.get_server_ip(interface_index=i), netmask) + self.topo.command_to(s, cmd) + server_interface_mac = s.intf(self.get_server_interface(i, 0)).MAC() + self.topo.command_to(self.router, "arp -s {} {}".format( + self.get_server_ip(interface_index=i), server_interface_mac)) + + def get_client_ip(self, interface_index, congestion_client=False): + return "{}{}.{}".format(self.param.get(TopoParameter.LEFT_SUBNET), interface_index, "10" if congestion_client else "1") + + def get_client_subnet(self, interface_index): + return "{}{}.0/24".format(self.param.get(TopoParameter.LEFT_SUBNET), interface_index) + + def get_router_ip_to_client_switch(self, switch_index): + return "{}{}.2".format(self.param.get(TopoParameter.LEFT_SUBNET), switch_index) + + def get_router_ip_to_server_switch(self, switch_index): + return "{}{}.2".format(self.param.get(TopoParameter.RIGHT_SUBNET), switch_index) + + def get_server_ip(self, interface_index=0): + return "{}{}.1".format(self.param.get(TopoParameter.RIGHT_SUBNET), interface_index) + + def get_server_subnet(self, interface_index): + return "{}{}.0/24".format(self.param.get(TopoParameter.RIGHT_SUBNET), interface_index) + + def client_interface_count(self): + return max(len(self.topo.c2r_client_switches), 1) + + def server_interface_count(self): + return max(len(self.servers), 1) + + def get_router_interface_to_server_switch(self, switch_index): + return self.get_router_interface_to_client_switch(len(self.topo.c2r_router_switches) + switch_index) + + def get_client_interface(self, client_index, interface_index): + return "{}-eth{}".format(self.topo.get_client_name(client_index), interface_index) + + def get_router_interface_to_client_switch(self, interface_index): + return "{}-eth{}".format(self.topo.get_router_name(0), interface_index) + + def get_server_interface(self, server_index, interface_index): + return "{}-eth{}".format(self.topo.get_server_name(server_index), interface_index) \ No newline at end of file diff --git a/topos/two_interface_congestion.py b/topos/two_interface_congestion.py deleted file mode 100644 index ae0fdd6..0000000 --- a/topos/two_interface_congestion.py +++ /dev/null @@ -1,245 +0,0 @@ -from core.topo import Topo, TopoConfig, TopoParameter - - -class TwoInterfaceCongestionTopo(Topo): - NAME = "twoIfCong" - - def __init__(self, topo_builder, parameterFile): - raise Exception("Broken") - super(TwoInterfaceCongestionTopo, self).__init__(topo_builder, parameterFile) - - print("Hello from topo two ifs cong") - print("Expected topo:") - print("c1----link0--------------|") - print("|-------------r1--link1--r2-----s1") - print(" | |------s2") - print("c2----link2----") - - self.client = self.add_host(Topo.CLIENT_NAME) - self.clientCong = self.add_host(Topo.CLIENT_NAME + "Cong") - self.server = self.add_host(Topo.SERVER_NAME) - self.serverCong = self.add_host(Topo.SERVER_NAME + "Cong") - self.router = self.add_host(Topo.ROUTER_NAME) - self.routerCong = self.add_host(Topo.ROUTER_NAME + "Cong") - self.switch = [] - - # Link between c1 and r2 - self.switch.append(self.addOneSwitchPerLink(self.topo_parameter.link_characteristics[0])) - self.add_link(self.client, self.switch[-1]) - self.add_link(self.switch[-1], self.router, **self.topo_parameter.link_characteristics[0].as_dict()) - - # Link between c1 and r1 - self.add_link(self.client, self.routerCong) - - # Link between c2 and r1 - self.switch.append(self.addOneSwitchPerLink(self.topo_parameter.link_characteristics[2])) - self.add_link(self.clientCong, self.switch[-1]) - self.add_link(self.switch[-1], self.routerCong, **self.topo_parameter.link_characteristics[2].as_dict()) - - # Link between r1 and r2 - self.switch.append(self.addOneSwitchPerLink(self.topo_parameter.link_characteristics[1])) - self.add_link(self.routerCong, self.switch[-1]) - self.add_link(self.switch[-1], self.router, **self.topo_parameter.link_characteristics[1].as_dict()) - - # Link between r2 and s1 - self.add_link(self.router, self.server) - - # Link between r2 and s2 - self.add_link(self.router, self.serverCong) - - def __str__(self): - s = "Hello from topo two ifs cong \n" - s = s + "c1----link0--------------| \n" - s = s + "|-------------r1--link1--r2-----s1 \n" - s = s + " | |------s2 \n" - s = s + "c2----link2---- \n" - return s - - def addOneSwitchPerLink(self, link): - return self.add_switch(Topo.SWITCH_NAME_PREFIX + str(link.id)) - - -class TwoInterfaceCongestionConfig(TopoConfig): - NAME = "twoIfCong" - - def __init__(self, topo, param): - super(TwoInterfaceCongestionConfig, self).__init__(topo, param) - - def configure_routing(self): - # Client - Router - cmd = self.add_table_route_command("10.0.0.1", 0) - self.topo.command_to(self.client, cmd) - cmd = self.add_link_scope_route_command("10.0.0.0/24", Topo.CLIENT_NAME + "-eth0", 0) - self.topo.command_to(self.client, cmd) - cmd = self.add_table_default_route_command("10.0.0.2", 0) - self.topo.command_to(self.client, cmd) - - # Client -> Router cong - cmd = self.add_table_route_command("10.0.1.1", 1) - self.topo.command_to(self.client, cmd) - cmd = self.add_link_scope_route_command("10.0.1.0/24", Topo.CLIENT_NAME + "-eth1", 1) - self.topo.command_to(self.client, cmd) - cmd = self.add_table_default_route_command("10.0.1.2", 1) - self.topo.command_to(self.client, cmd) - - # Client cong -> Router cong - cmd = self.add_table_route_command("10.0.2.1", 0) - self.topo.command_to(self.clientCong, cmd) - cmd = self.add_link_scope_route_command("10.0.2.0/24", Topo.CLIENT_NAME + "Cong-eth0", 0) - self.topo.command_to(self.clientCong, cmd) - cmd = self.add_table_default_route_command("10.0.2.2", 0) - self.topo.command_to(self.clientCong, cmd) - - # Router cong -> Router - cmd = self.add_table_route_command("10.0.3.1", 0) - self.topo.command_to(self.routerCong, cmd) - cmd = self.add_link_scope_route_command("10.1.0.0/16", Topo.ROUTER_NAME + "Cong-eth2", 0) - self.topo.command_to(self.routerCong, cmd) - cmd = self.add_table_default_route_command("10.0.3.2", 0) - self.topo.command_to(self.routerCong, cmd) - - # Router -> Router cong - cmd = self.add_table_route_command("10.0.3.2", 0) - self.topo.command_to(self.router, cmd) - cmd = self.add_link_scope_route_command("10.0.0.0/16", Topo.ROUTER_NAME + "-eth1", 0) - self.topo.command_to(self.router, cmd) - cmd = self.add_table_default_route_command("10.0.3.1", 0) - self.topo.command_to(self.router, cmd) - - # Default route Client - cmd = self.add_global_default_route_command("10.0.0.2", Topo.CLIENT_NAME + "-eth0") - self.topo.command_to(self.client, cmd) - - # Default route Client cong - cmd = self.add_global_default_route_command("10.0.2.2", Topo.CLIENT_NAME + "Cong-eth0") - self.topo.command_to(self.clientCong, cmd) - - # Default route Router cong - cmd = self.add_global_default_route_command("10.0.3.2", Topo.ROUTER_NAME + "Cong-eth2") - self.topo.command_to(self.routerCong, cmd) - - # Default route Router - cmd = self.add_global_default_route_command("10.0.3.1", Topo.ROUTER_NAME + "-eth1") - self.topo.command_to(self.router, cmd) - - # Default route Server - cmd = self.add_global_default_route_command("10.1.0.2", Topo.SERVER_NAME + "-eth0") - self.topo.command_to(self.server, cmd) - - # Default route Server cong - cmd = self.add_global_default_route_command("10.1.1.2", Topo.SERVER_NAME + "Cong-eth0") - self.topo.command_to(self.serverCong, cmd) - - def configureInterface(self, srcHost, dstHost, srcInterfaceName, srcIP, netmask): - cmd = self.interface_up_command(srcInterfaceName, srcIP, netmask) - self.topo.command_to(srcHost, cmd) - mac = srcHost.intf(srcInterfaceName).MAC() - cmd = self.arp_command(srcIP, mac) - self.topo.command_to(dstHost, cmd) - - def configure_interfaces(self): - print("Configure interfaces for two inf cong") - self.client = self.topo.get_host(Topo.CLIENT_NAME) - self.clientCong = self.topo.get_host(Topo.CLIENT_NAME + "Cong") - self.server = self.topo.get_host(Topo.SERVER_NAME) - self.serverCong = self.topo.get_host(Topo.SERVER_NAME + "Cong") - self.router = self.topo.get_host(Topo.ROUTER_NAME) - self.routerCong = self.topo.get_host(Topo.ROUTER_NAME + "Cong") - netmask = "255.255.255.0" - links = self.topo.get_link_characteristics() - - # Link 0: Client - Router - self.configureInterface(self.client, self.router, Topo.CLIENT_NAME + "-eth0", "10.0.0.1", netmask) - - if(links[0].backup): - cmd = self.interface_backup_command(Topo.CLIENT_NAME + "-eth0") - self.topo.command_to(self.client, cmd) - - self.configureInterface(self.router, self.client, Topo.ROUTER_NAME + "-eth0", "10.0.0.2", netmask) - print(str(links[0])) - - # Client - Router cong - self.configureInterface(self.client, self.routerCong, Topo.CLIENT_NAME + "-eth1", "10.0.1.1", netmask) - - if(links[1].backup): - cmd = self.interface_backup_command(Topo.CLIENT_NAME + "-eth1") - self.topo.command_to(self.client, cmd) - - self.configureInterface(self.routerCong, self.client, Topo.ROUTER_NAME + "Cong-eth0", "10.0.1.2", netmask) - - # Link 1: Router - Router cong - self.configureInterface(self.routerCong, self.router, Topo.ROUTER_NAME + "Cong-eth2", "10.0.3.1", netmask) - self.configureInterface(self.router, self.routerCong, Topo.ROUTER_NAME + "-eth1", "10.0.3.2", netmask) - print(str(links[1])) - - # Link 2: Client cong - Router cong - self.configureInterface(self.clientCong, self.routerCong, Topo.CLIENT_NAME + "Cong-eth0", "10.0.2.1", netmask) - self.configureInterface(self.routerCong, self.clientCong, Topo.ROUTER_NAME + "Cong-eth1", "10.0.2.2", netmask) - print(str(links[2])) - - # Router - Server - self.configureInterface(self.server, self.router, Topo.SERVER_NAME + "-eth0", "10.1.0.1", netmask) - self.configureInterface(self.router, self.server, Topo.ROUTER_NAME + "-eth2", "10.1.0.2", netmask) - - # Router - Server cong - self.configureInterface(self.serverCong, self.router, Topo.SERVER_NAME + "Cong-eth0", "10.1.1.1", netmask) - self.configureInterface(self.router, self.serverCong, Topo.ROUTER_NAME + "-eth3", "10.1.1.2", netmask) - - def get_client_ip(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - clientIP = lSubnet + str(interfaceID) + ".1" - return clientIP - - def getClientSubnet(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - clientSubnet = lSubnet + str(interfaceID) + ".0/24" - return clientSubnet - - def getClientCongIP(self): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - clientIP = lSubnet + str(2) + ".1" - return clientIP - - def getClientCongSubnet(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - clientSubnet = lSubnet + str(128) + ".0/24" - return clientSubnet - - def getRouterIPSwitch(self, interfaceID): - lSubnet = self.param.get(TopoParameter.LEFT_SUBNET) - routerIP = lSubnet + str(interfaceID) + ".2" - return routerIP - - def getRouterIPServer(self): - rSubnet = self.param.get(TopoParameter.RIGHT_SUBNET) - routerIP = rSubnet + "0.2" - return routerIP - - def get_server_ip(self): - rSubnet = self.param.get(TopoParameter.RIGHT_SUBNET) - serverIP = rSubnet + "0.1" - return serverIP - - def client_interface_count(self): - return len(self.topo.switch) - - def get_router_interface_to_server(self): - return self.get_router_interface_to_switch(len(self.topo.switch)) - - def get_client_interface(self, interfaceID): - return Topo.CLIENT_NAME + "-eth" + str(interfaceID) - - def get_router_interface_to_switch(self, interfaceID): - return Topo.ROUTER_NAME + "-eth" + str(interfaceID) - - def get_server_interface(self): - return Topo.SERVER_NAME + "-eth0" - - def getMidLeftName(self, id): - return Topo.SWITCH_NAME_PREFIX + str(id) - - def getMidRightName(self, id): - if id == 2: - return Topo.ROUTER_NAME + "Cong" - - return Topo.ROUTER_NAME