more elegant definition of paths between client/router and router/server
This commit is contained in:
parent
c066bc4ccd
commit
883771cd53
@ -1,5 +1,5 @@
|
|||||||
leftSubnet:10.0.
|
leftSubnet:10.0.
|
||||||
rightSubnet:10.1.
|
rightSubnet:10.1.
|
||||||
path_0:10,10,4
|
path_c2r_0:10,10,4
|
||||||
path_1:40,30,4
|
path_c2r_1:40,30,4
|
||||||
topoType:MultiIf
|
topoType:MultiIf
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
leftSubnet:10.0.
|
leftSubnet:10.0.
|
||||||
rightSubnet:10.1.
|
rightSubnet:10.1.
|
||||||
path_0:100,20,4
|
path_c2r_0:100,20,4
|
||||||
path_1:1,20,4
|
path_c2r_1:1,20,4
|
||||||
|
path_r2s_0:10,20,10
|
||||||
topoType:MultiIf
|
topoType:MultiIf
|
||||||
|
5
config/topo/topo_3
Normal file
5
config/topo/topo_3
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
leftSubnet:10.0.
|
||||||
|
rightSubnet:10.1.
|
||||||
|
path_c2r_0:100,20,4
|
||||||
|
path_r2s_0:10,20,10
|
||||||
|
topoType:MultiIf
|
8
config/topo/topo_4
Normal file
8
config/topo/topo_4
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
leftSubnet:10.0.
|
||||||
|
rightSubnet:10.1.
|
||||||
|
path_c2r_0:100,20,4
|
||||||
|
path_c2r_1:100,20,4
|
||||||
|
path_c2r_2:100,20,4
|
||||||
|
path_r2s_0:10,20,10
|
||||||
|
path_r2s_1:10,20,10
|
||||||
|
topoType:MultiIf
|
8
config/topo/topo_5
Normal file
8
config/topo/topo_5
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
leftSubnet:10.0.
|
||||||
|
rightSubnet:10.1.
|
||||||
|
path_c2r_0:100,20,4
|
||||||
|
path_c2r_1:100,20,4
|
||||||
|
path_r2s_0:10,20,10
|
||||||
|
path_r2s_1:10,20,10
|
||||||
|
path_r2s_2:10,20,10
|
||||||
|
topoType:MultiIf
|
@ -179,24 +179,24 @@ class Experiment(object):
|
|||||||
self.topo.command_to(self.topo_config.client, "{} link set dev {} priority {}".format(
|
self.topo.command_to(self.topo_config.client, "{} link set dev {} priority {}".format(
|
||||||
Experiment.IP_BIN, self.topo_config.get_client_interface(0), priority_path_0))
|
Experiment.IP_BIN, self.topo_config.get_client_interface(0), priority_path_0))
|
||||||
self.topo.command_to(self.topo_config.router, "{} link set dev {} priority {}".format(
|
self.topo.command_to(self.topo_config.router, "{} link set dev {} priority {}".format(
|
||||||
Experiment.IP_BIN, self.topo_config.get_router_interface_to_switch(0), priority_path_0))
|
Experiment.IP_BIN, self.topo_config.get_router_interface_to_client_switch(0), priority_path_0))
|
||||||
self.topo.command_to(self.topo_config.client, "{} link set dev {} priority {}".format(
|
self.topo.command_to(self.topo_config.client, "{} link set dev {} priority {}".format(
|
||||||
Experiment.IP_BIN, self.topo_config.get_client_interface(1), priority_path_1))
|
Experiment.IP_BIN, self.topo_config.get_client_interface(1), priority_path_1))
|
||||||
self.topo.command_to(self.topo_config.router, "{} link set dev {} priority {}".format(
|
self.topo.command_to(self.topo_config.router, "{} link set dev {} priority {}".format(
|
||||||
Experiment.IP_BIN, self.topo_config.get_router_interface_to_switch(1), priority_path_1))
|
Experiment.IP_BIN, self.topo_config.get_router_interface_to_client_switch(1), priority_path_1))
|
||||||
|
|
||||||
backup_path_0 = self.experiment_parameter.get(ExperimentParameter.BACKUP_PATH_0)
|
backup_path_0 = self.experiment_parameter.get(ExperimentParameter.BACKUP_PATH_0)
|
||||||
if int(backup_path_0) > 0:
|
if int(backup_path_0) > 0:
|
||||||
self.topo.command_to(self.topo_config.client,
|
self.topo.command_to(self.topo_config.client,
|
||||||
self.topo_config.interface_backup_command(self.topo_config.get_client_interface(0)))
|
self.topo_config.interface_backup_command(self.topo_config.get_client_interface(0)))
|
||||||
self.topo.command_to(self.topo_config.router,
|
self.topo.command_to(self.topo_config.router,
|
||||||
self.topo_config.interface_backup_command(self.topo_config.get_router_interface_to_switch(0)))
|
self.topo_config.interface_backup_command(self.topo_config.get_router_interface_to_client_switch(0)))
|
||||||
backup_path_1 = self.experiment_parameter.get(ExperimentParameter.BACKUP_PATH_1)
|
backup_path_1 = self.experiment_parameter.get(ExperimentParameter.BACKUP_PATH_1)
|
||||||
if int(backup_path_1) > 0:
|
if int(backup_path_1) > 0:
|
||||||
self.topo.command_to(self.topo_config.client,
|
self.topo.command_to(self.topo_config.client,
|
||||||
self.topo_config.interface_backup_command(self.topo_config.get_client_interface(1)))
|
self.topo_config.interface_backup_command(self.topo_config.get_client_interface(1)))
|
||||||
self.topo.command_to(self.topo_config.router,
|
self.topo.command_to(self.topo_config.router,
|
||||||
self.topo_config.interface_backup_command(self.topo_config.get_router_interface_to_switch(1)))
|
self.topo_config.interface_backup_command(self.topo_config.get_router_interface_to_client_switch(1)))
|
||||||
|
|
||||||
def run_userspace_path_manager(self):
|
def run_userspace_path_manager(self):
|
||||||
"""
|
"""
|
||||||
@ -364,7 +364,7 @@ class Experiment(object):
|
|||||||
count = self.experiment_parameter.get(ExperimentParameter.PING_COUNT)
|
count = self.experiment_parameter.get(ExperimentParameter.PING_COUNT)
|
||||||
for i in range(0, self.topo_config.client_interface_count()):
|
for i in range(0, self.topo_config.client_interface_count()):
|
||||||
cmd = self.ping_command(self.topo_config.get_client_ip(i),
|
cmd = self.ping_command(self.topo_config.get_client_ip(i),
|
||||||
self.topo_config.get_server_ip(), n=count)
|
self.topo_config.get_server_ip(interface_index=0), n=count)
|
||||||
logging.info(cmd)
|
logging.info(cmd)
|
||||||
self.topo.command_to(self.topo_config.client, cmd)
|
self.topo.command_to(self.topo_config.client, cmd)
|
||||||
|
|
||||||
|
121
core/topo.py
121
core/topo.py
@ -17,12 +17,22 @@ class NetemAt(object):
|
|||||||
return "netem at {} ({}) will be {}".format(self.at, self.delta, self.cmd)
|
return "netem at {} ({}) will be {}".format(self.at, self.delta, self.cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def get_bandwidth_delay_product_divided_by_mtu(delay, bandwidth):
|
||||||
|
"""
|
||||||
|
With delay in ms, bandwidth in Mbps
|
||||||
|
"""
|
||||||
|
rtt = 2 * float(delay)
|
||||||
|
bandwidth_delay_product = (float(bandwidth) * 125000.0) * (rtt / 1000.0)
|
||||||
|
return int(math.ceil(bandwidth_delay_product * 1.0 / 1500.0))
|
||||||
|
|
||||||
|
|
||||||
class LinkCharacteristics(object):
|
class LinkCharacteristics(object):
|
||||||
"""
|
"""
|
||||||
Network characteristics associated to a link
|
Network characteristics associated to a link
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
id the identifier of the link
|
id the identifier of the link
|
||||||
|
link_type type of the link
|
||||||
delay the one-way delay introduced by the link in ms
|
delay the one-way delay introduced by the link in ms
|
||||||
queue_size the size of the link buffer, in packets
|
queue_size the size of the link buffer, in packets
|
||||||
bandwidth the bandwidth of the link in Mbps
|
bandwidth the bandwidth of the link in Mbps
|
||||||
@ -31,8 +41,9 @@ class LinkCharacteristics(object):
|
|||||||
netem_at list of NetemAt instances applicable to the link
|
netem_at list of NetemAt instances applicable to the link
|
||||||
backup integer indicating if this link is a backup one or not (useful for MPTCP)
|
backup integer indicating if this link is a backup one or not (useful for MPTCP)
|
||||||
"""
|
"""
|
||||||
def __init__(self, id, delay, queue_size, bandwidth, loss, backup=False):
|
def __init__(self, id, link_type, delay, queue_size, bandwidth, loss, backup=0):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
self.link_type = link_type
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
self.queue_size = queue_size
|
self.queue_size = queue_size
|
||||||
self.bandwidth = bandwidth
|
self.bandwidth = bandwidth
|
||||||
@ -45,10 +56,7 @@ class LinkCharacteristics(object):
|
|||||||
"""
|
"""
|
||||||
Get the bandwidth-delay product in terms of packets (hence, dividing by the MTU)
|
Get the bandwidth-delay product in terms of packets (hence, dividing by the MTU)
|
||||||
"""
|
"""
|
||||||
rtt = 2 * float(self.delay)
|
return get_bandwidth_delay_product_divided_by_mtu(self.delay, self.bandwidth)
|
||||||
""" Since bandwidth is in Mbps and rtt in ms """
|
|
||||||
bandwidth_delay_product = (float(self.bandwidth) * 125000.0) * (rtt / 1000.0)
|
|
||||||
return int(math.ceil(bandwidth_delay_product * 1.0 / 1500.0))
|
|
||||||
|
|
||||||
def buffer_size(self):
|
def buffer_size(self):
|
||||||
"""
|
"""
|
||||||
@ -116,6 +124,8 @@ class LinkCharacteristics(object):
|
|||||||
Notably used by BottleneckLink
|
Notably used by BottleneckLink
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
|
"link_id": self.id,
|
||||||
|
"link_type": self.link_type,
|
||||||
"bw": float(self.bandwidth),
|
"bw": float(self.bandwidth),
|
||||||
"delay": "{}ms".format(self.delay),
|
"delay": "{}ms".format(self.delay),
|
||||||
"loss": float(self.loss),
|
"loss": float(self.loss),
|
||||||
@ -124,13 +134,14 @@ class LinkCharacteristics(object):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return """
|
return """
|
||||||
|
Link type: {}
|
||||||
Link id: {}
|
Link id: {}
|
||||||
Delay: {}
|
Delay: {}
|
||||||
Queue Size: {}
|
Queue Size: {}
|
||||||
Bandwidth: {}
|
Bandwidth: {}
|
||||||
Loss: {}
|
Loss: {}
|
||||||
Backup: {}
|
Backup: {}
|
||||||
""".format(self.id, self.delay, self.queue_size, self.bandwidth, self.loss, self.backup) + \
|
""".format(self.link_type, self.id, self.delay, self.queue_size, self.bandwidth, self.loss, self.backup) + \
|
||||||
"".join(["\t {} \n".format(n) for n in self.netem_at])
|
"".join(["\t {} \n".format(n) for n in self.netem_at])
|
||||||
|
|
||||||
|
|
||||||
@ -139,13 +150,11 @@ class TopoParameter(Parameter):
|
|||||||
RIGHT_SUBNET = "rightSubnet"
|
RIGHT_SUBNET = "rightSubnet"
|
||||||
NETEM_AT = "netem_at_"
|
NETEM_AT = "netem_at_"
|
||||||
CHANGE_NETEM = "changeNetem"
|
CHANGE_NETEM = "changeNetem"
|
||||||
SERVER_PATHS = "serverPaths"
|
|
||||||
|
|
||||||
DEFAULT_PARAMETERS = {
|
DEFAULT_PARAMETERS = {
|
||||||
LEFT_SUBNET: "10.1.",
|
LEFT_SUBNET: "10.1.",
|
||||||
RIGHT_SUBNET: "10.2.",
|
RIGHT_SUBNET: "10.2.",
|
||||||
CHANGE_NETEM: "false",
|
CHANGE_NETEM: "false",
|
||||||
SERVER_PATHS: "1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, parameter_filename):
|
def __init__(self, parameter_filename):
|
||||||
@ -184,34 +193,63 @@ class TopoParameter(Parameter):
|
|||||||
|
|
||||||
logging.info(self.link_characteristics[link_id].netem_at)
|
logging.info(self.link_characteristics[link_id].netem_at)
|
||||||
|
|
||||||
|
def parse_link_id_and_type(self, key):
|
||||||
|
"""
|
||||||
|
The key of a path must have the following format:
|
||||||
|
path_{link_type}_{ID}
|
||||||
|
|
||||||
|
Note that several links can have the same ID, several links can have the same
|
||||||
|
link_type, but the tuple (link_type, ID) is unique.
|
||||||
|
"""
|
||||||
|
_, link_type, link_id = key.split("_")
|
||||||
|
return link_type, int(link_id)
|
||||||
|
|
||||||
|
def parse_link_characteristics(self, value):
|
||||||
|
"""
|
||||||
|
The format of a link characteristic is one of the following:
|
||||||
|
- "{delay},{queue_size},{bandwidth},{loss_perc},{is_backup}"
|
||||||
|
- "{delay},{queue_size},{bandwidth},{loss_perc}"
|
||||||
|
- "{delay},{queue_size},{bandwidth}"
|
||||||
|
- "{delay},{bandwidth}"
|
||||||
|
|
||||||
|
When not specified, default values are the following:
|
||||||
|
- queue_size: get_bandwidth_delay_product_divided_by_mtu(delay, bandwidth)
|
||||||
|
- loss_perc: 0
|
||||||
|
- is_backup: 0
|
||||||
|
|
||||||
|
Return
|
||||||
|
delay, bandwidth, queue_size, loss_perc, is_backup
|
||||||
|
"""
|
||||||
|
loss_perc, is_backup = 0.0, 0
|
||||||
|
c = value.split(",")
|
||||||
|
if len(c) == 2:
|
||||||
|
delay, bw = float(c[0]), float(c[1])
|
||||||
|
return delay, bw, get_bandwidth_delay_product_divided_by_mtu(delay, bw), loss_perc, is_backup
|
||||||
|
if len(c) == 3:
|
||||||
|
return float(c[0]), float(c[2]), int(c[1]), loss_perc, is_backup
|
||||||
|
if len(c) == 4:
|
||||||
|
return float(c[0]), float(c[2]), int(c[1]), float(c[3]), is_backup
|
||||||
|
if len(c) == 5:
|
||||||
|
return float(c[0]), float(c[2]), int(c[1]), float(c[3]), int(c[4])
|
||||||
|
|
||||||
|
raise ValueError("Invalid link characteristics: {}".format(value))
|
||||||
|
|
||||||
def load_link_characteristics(self):
|
def load_link_characteristics(self):
|
||||||
"""
|
"""
|
||||||
CAUTION: the path_i in config file is not taken into account. Hence place them in
|
Load the path characteristics
|
||||||
increasing order in the topo parameter file!
|
|
||||||
"""
|
"""
|
||||||
i = 0
|
|
||||||
for k in sorted(self.parameters):
|
for k in sorted(self.parameters):
|
||||||
# TODO FIXME rewrite this function
|
|
||||||
if k.startswith("path"):
|
if k.startswith("path"):
|
||||||
tab = self.parameters[k].split(",")
|
|
||||||
bup = False
|
|
||||||
loss = "0.0"
|
|
||||||
if len(tab) == 5:
|
|
||||||
loss = tab[3]
|
|
||||||
bup = tab[4].lower() == 'true'
|
|
||||||
if len(tab) == 4:
|
|
||||||
try:
|
try:
|
||||||
loss = float(tab[3])
|
link_type, link_id = self.parse_link_id_and_type(k)
|
||||||
loss = tab[3]
|
delay, bw, queue_size, loss_perc, is_backup = self.parse_link_characteristics(
|
||||||
except ValueError:
|
self.parameters[k])
|
||||||
bup = tab[3].lower() == 'true'
|
except ValueError as e:
|
||||||
if len(tab) == 3 or len(tab) == 4 or len(tab) == 5:
|
logging.error("Ignored path {}: {}".format(k, e))
|
||||||
path = LinkCharacteristics(i, tab[0],
|
|
||||||
tab[1], tab[2], loss, bup)
|
|
||||||
self.link_characteristics.append(path)
|
|
||||||
i = i + 1
|
|
||||||
else:
|
else:
|
||||||
logging.warning("Ignored path {}".format(self.parameters[k]))
|
path = LinkCharacteristics(link_id, link_type, delay, bw,
|
||||||
|
queue_size, loss_perc, backup=is_backup)
|
||||||
|
self.link_characteristics.append(path)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
s = "{}".format(super(TopoParameter, self).__str__())
|
s = "{}".format(super(TopoParameter, self).__str__())
|
||||||
@ -248,7 +286,8 @@ class BottleneckLink(object):
|
|||||||
topo_builder.add_link(self.bs2, self.bs3)
|
topo_builder.add_link(self.bs2, self.bs3)
|
||||||
|
|
||||||
def get_bs_name(self, index):
|
def get_bs_name(self, index):
|
||||||
return "{}_{}_{}".format(BottleneckLink.BOTTLENECK_SWITCH_NAME_PREFIX, self.link_characteristics.id, index)
|
return "{}_{}_{}_{}".format(BottleneckLink.BOTTLENECK_SWITCH_NAME_PREFIX,
|
||||||
|
self.link_characteristics.link_type, self.link_characteristics.id, index)
|
||||||
|
|
||||||
def reinit_variables(self):
|
def reinit_variables(self):
|
||||||
# Required to retrieve actual nodes
|
# Required to retrieve actual nodes
|
||||||
@ -534,15 +573,33 @@ class TopoConfig(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def server_interface_count(self):
|
||||||
|
"""
|
||||||
|
Return the number of server's interfaces, without lo
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_client_interface(self, client_index, interface_index):
|
def get_client_interface(self, client_index, interface_index):
|
||||||
"""
|
"""
|
||||||
Return the interface with index `interface_index` of the client with index `client_index`
|
Return the interface with index `interface_index` of the client with index `client_index`
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_router_interface_to_switch(self, index):
|
def get_server_interface(self, server_index, interface_index):
|
||||||
"""
|
"""
|
||||||
Return the router's interface to switch with index `index`
|
Return the interface with index `interface_index` of the server with index `server_index`
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def get_router_interface_to_client_switch(self, index):
|
||||||
|
"""
|
||||||
|
Return the router's interface to client's switch with index `index`
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def get_router_interface_to_server_switch(self, index):
|
||||||
|
"""
|
||||||
|
Return the router's interface to server's switch with index `index`
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@ -11,41 +11,86 @@ class MultiInterfaceTopo(Topo):
|
|||||||
self.client = self.add_client()
|
self.client = self.add_client()
|
||||||
self.server = self.add_server()
|
self.server = self.add_server()
|
||||||
self.router = self.add_router()
|
self.router = self.add_router()
|
||||||
self.client_switches = []
|
self.c2r_client_switches = []
|
||||||
self.server_switches = []
|
self.c2r_router_switches = []
|
||||||
for l in self.topo_parameter.link_characteristics:
|
self.r2s_router_switches = []
|
||||||
self.client_switches.append(self.add_client_side_switch(l))
|
self.r2s_server_switches = []
|
||||||
self.add_link(self.client,self.client_switches[-1])
|
|
||||||
self.server_switches.append(self.add_router_side_switch(l))
|
|
||||||
self.add_bottleneck_link(self.client_switches[-1], self.server_switches[-1], link_characteristics=l)
|
|
||||||
self.add_link(self.server_switches[-1],self.router)
|
|
||||||
|
|
||||||
for i in range(int(self.topo_parameter.get(TopoParameter.SERVER_PATHS))):
|
# Add client - router links
|
||||||
|
for l in self.get_client_to_router_links():
|
||||||
|
self.c2r_client_switches.append(self.add_c2r_client_side_switch(l))
|
||||||
|
self.add_link(self.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)
|
||||||
|
|
||||||
|
# Special case: if there is no specified link between router and server, directly connect them!
|
||||||
|
if len(self.get_router_to_server_links()) > 0:
|
||||||
|
for l in self.get_router_to_server_links():
|
||||||
|
self.r2s_router_switches.append(self.add_r2s_router_side_switch(l))
|
||||||
|
self.add_link(self.router, self.r2s_router_switches[-1])
|
||||||
|
self.r2s_server_switches.append(self.add_r2s_server_side_switch(l))
|
||||||
|
self.add_bottleneck_link(self.r2s_router_switches[-1], self.r2s_server_switches[-1], link_characteristics=l)
|
||||||
|
self.add_link(self.r2s_server_switches[-1], self.server)
|
||||||
|
else:
|
||||||
self.add_link(self.router, self.server)
|
self.add_link(self.router, self.server)
|
||||||
|
|
||||||
def add_client_side_switch(self, link):
|
|
||||||
return self.add_switch("{}{}".format(MultiInterfaceTopo.SWITCH_NAME_PREFIX, 2 * link.id))
|
|
||||||
|
|
||||||
def add_router_side_switch(self, link):
|
def get_client_to_router_links(self):
|
||||||
return self.add_switch("{}{}".format(MultiInterfaceTopo.SWITCH_NAME_PREFIX, 2 * link.id + 1))
|
return [l for l in self.topo_parameter.link_characteristics if l.link_type == "c2r"]
|
||||||
|
|
||||||
|
def get_router_to_server_links(self):
|
||||||
|
return [l for l in self.topo_parameter.link_characteristics if l.link_type == "r2s"]
|
||||||
|
|
||||||
|
def add_c2r_client_side_switch(self, link):
|
||||||
|
return self.add_switch("{}c2r{}".format(MultiInterfaceTopo.SWITCH_NAME_PREFIX, 2 * link.id))
|
||||||
|
|
||||||
|
def add_c2r_router_side_switch(self, link):
|
||||||
|
return self.add_switch("{}c2r{}".format(MultiInterfaceTopo.SWITCH_NAME_PREFIX, 2 * link.id + 1))
|
||||||
|
|
||||||
|
def add_r2s_router_side_switch(self, link):
|
||||||
|
return self.add_switch("{}r2s{}".format(MultiInterfaceTopo.SWITCH_NAME_PREFIX, 2 * link.id))
|
||||||
|
|
||||||
|
def add_r2s_server_side_switch(self, link):
|
||||||
|
return self.add_switch("{}r2s{}".format(MultiInterfaceTopo.SWITCH_NAME_PREFIX, 2 * link.id + 1))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
s = "Simple multiple interface topolgy \n"
|
s = "Simple multiple interface topology \n"
|
||||||
i = 0
|
i = 0
|
||||||
n = len(self.topo_parameter.link_characteristics)
|
nc = len(self.get_client_to_router_links())
|
||||||
for p in self.topo_parameter.link_characteristics:
|
ns = len(self.get_router_to_server_links())
|
||||||
if i == n // 2:
|
m = max(nc, ns)
|
||||||
if n % 2 == 0:
|
skipped = 0
|
||||||
s = s + "c r-----s\n"
|
for i in range(0, m):
|
||||||
s = s + "|--sw----sw--|\n"
|
if i == m // 2:
|
||||||
|
if m % 2 == 0:
|
||||||
|
s = s + "c r--sw---bl---sw--s\n"
|
||||||
|
s = s + " \-sw---bl---sw-/\n"
|
||||||
else:
|
else:
|
||||||
s = s + "c--sw----sw--r-----s\n"
|
s = s + "c--sw---bl---sw--r--sw---bl---sw--s\n"
|
||||||
else:
|
else:
|
||||||
s = s + "|--sw----sw--|\n"
|
if i < m // 2:
|
||||||
|
if (nc == m and ns + skipped == m) or (ns == m and nc + skipped == m):
|
||||||
|
s = s + " /-sw---bl---sw-\ /-sw---bl---sw-\ \n"
|
||||||
|
elif nc == m:
|
||||||
|
s = s + " /-sw---bl---sw-\ \n"
|
||||||
|
skipped += 1
|
||||||
|
else:
|
||||||
|
s = s + " /-sw---bl---sw-\ \n"
|
||||||
|
skipped += 1
|
||||||
|
else:
|
||||||
|
if (nc == m and ns + skipped == m) or (ns == m and nc + skipped == m):
|
||||||
|
s = s + " \-sw---bl---sw-/ \-sw---bl---sw-/ \n"
|
||||||
|
elif nc == m:
|
||||||
|
s = s + " \-sw---bl---sw-/ \n"
|
||||||
|
skipped += 1
|
||||||
|
else:
|
||||||
|
s = s + " \-sw---bl---sw-/ \n"
|
||||||
|
skipped += 1
|
||||||
|
|
||||||
i = i + 1
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
class MultiInterfaceConfig(TopoConfig):
|
class MultiInterfaceConfig(TopoConfig):
|
||||||
NAME = "MultiIf"
|
NAME = "MultiIf"
|
||||||
|
|
||||||
@ -53,7 +98,7 @@ class MultiInterfaceConfig(TopoConfig):
|
|||||||
super(MultiInterfaceConfig, self).__init__(topo, param)
|
super(MultiInterfaceConfig, self).__init__(topo, param)
|
||||||
|
|
||||||
def configure_routing(self):
|
def configure_routing(self):
|
||||||
for i, l in enumerate(self.topo.client_switches):
|
for i, l in enumerate(self.topo.c2r_client_switches):
|
||||||
cmd = self.add_table_route_command(self.get_client_ip(i), i)
|
cmd = self.add_table_route_command(self.get_client_ip(i), i)
|
||||||
self.topo.command_to(self.client, cmd)
|
self.topo.command_to(self.client, cmd)
|
||||||
|
|
||||||
@ -66,7 +111,7 @@ class MultiInterfaceConfig(TopoConfig):
|
|||||||
i)
|
i)
|
||||||
self.topo.command_to(self.client, cmd)
|
self.topo.command_to(self.client, cmd)
|
||||||
|
|
||||||
for i in range(int(self.topo.topo_parameter.get(TopoParameter.SERVER_PATHS))):
|
for i, l in enumerate(self.topo.r2s_server_switches):
|
||||||
cmd = self.add_table_route_command(self.get_server_ip(i), i)
|
cmd = self.add_table_route_command(self.get_server_ip(i), i)
|
||||||
self.topo.command_to(self.server, cmd)
|
self.topo.command_to(self.server, cmd)
|
||||||
|
|
||||||
@ -96,7 +141,7 @@ class MultiInterfaceConfig(TopoConfig):
|
|||||||
netmask = "255.255.255.0"
|
netmask = "255.255.255.0"
|
||||||
|
|
||||||
links = self.topo.get_link_characteristics()
|
links = self.topo.get_link_characteristics()
|
||||||
for i, l in enumerate(self.topo.client_switches):
|
for i, l in enumerate(self.topo.c2r_client_switches):
|
||||||
cmd = self.interface_up_command(self.get_client_interface(0, i), self.get_client_ip(i), netmask)
|
cmd = self.interface_up_command(self.get_client_interface(0, i), self.get_client_ip(i), netmask)
|
||||||
self.topo.command_to(self.client, cmd)
|
self.topo.command_to(self.client, cmd)
|
||||||
client_interface_mac = self.client.intf(self.get_client_interface(0, i)).MAC()
|
client_interface_mac = self.client.intf(self.get_client_interface(0, i)).MAC()
|
||||||
@ -106,23 +151,38 @@ class MultiInterfaceConfig(TopoConfig):
|
|||||||
cmd = self.interface_backup_command(self.get_client_interface(0, i))
|
cmd = self.interface_backup_command(self.get_client_interface(0, i))
|
||||||
self.topo.command_to(self.client, cmd)
|
self.topo.command_to(self.client, cmd)
|
||||||
|
|
||||||
for i, l in enumerate(self.topo.server_switches):
|
for i, l in enumerate(self.topo.c2r_router_switches):
|
||||||
cmd = self.interface_up_command(self.get_router_interface_to_switch(i),
|
cmd = self.interface_up_command(self.get_router_interface_to_client_switch(i),
|
||||||
self.get_router_ip_to_client_switch(i), netmask)
|
self.get_router_ip_to_client_switch(i), netmask)
|
||||||
self.topo.command_to(self.router, cmd)
|
self.topo.command_to(self.router, cmd)
|
||||||
router_interface_mac = self.router.intf(self.get_router_interface_to_switch(i)).MAC()
|
router_interface_mac = self.router.intf(self.get_router_interface_to_client_switch(i)).MAC()
|
||||||
self.topo.command_to(self.client, "arp -s {} {}".format(
|
self.topo.command_to(self.client, "arp -s {} {}".format(
|
||||||
self.get_router_ip_to_client_switch(i), router_interface_mac))
|
self.get_router_ip_to_client_switch(i), router_interface_mac))
|
||||||
|
|
||||||
for i in range(int(self.topo.topo_parameter.get(TopoParameter.SERVER_PATHS))):
|
if len(self.topo.r2s_router_switches) == 0:
|
||||||
cmd = self.interface_up_command(self.get_router_interface_to_server(i),
|
# Case no server param is specified
|
||||||
|
cmd = self.interface_up_command(self.get_router_interface_to_server_switch(0),
|
||||||
|
self.get_router_ip_to_server_switch(0), netmask)
|
||||||
|
self.topo.command_to(self.router, cmd)
|
||||||
|
router_interface_mac = self.router.intf(self.get_router_interface_to_server_switch(0)).MAC()
|
||||||
|
self.topo.command_to(self.server, "arp -s {} {}".format(
|
||||||
|
self.get_router_ip_to_server_switch(0), router_interface_mac))
|
||||||
|
|
||||||
|
cmd = self.interface_up_command(self.get_server_interface(0, 0), self.get_server_ip(0), netmask)
|
||||||
|
self.topo.command_to(self.server, cmd)
|
||||||
|
server_interface_mac = self.server.intf(self.get_server_interface(0, 0)).MAC()
|
||||||
|
self.topo.command_to(self.router, "arp -s {} {}".format(
|
||||||
|
self.get_server_ip(0), server_interface_mac))
|
||||||
|
|
||||||
|
for i, l in enumerate(self.topo.r2s_router_switches):
|
||||||
|
cmd = self.interface_up_command(self.get_router_interface_to_server_switch(i),
|
||||||
self.get_router_ip_to_server_switch(i), netmask)
|
self.get_router_ip_to_server_switch(i), netmask)
|
||||||
self.topo.command_to(self.router, cmd)
|
self.topo.command_to(self.router, cmd)
|
||||||
router_interface_mac = self.router.intf(self.get_router_interface_to_server(i)).MAC()
|
router_interface_mac = self.router.intf(self.get_router_interface_to_server_switch(i)).MAC()
|
||||||
self.topo.command_to(self.server, "arp -s {} {}".format(
|
self.topo.command_to(self.server, "arp -s {} {}".format(
|
||||||
self.get_router_ip_to_server_switch(i), router_interface_mac))
|
self.get_router_ip_to_server_switch(i), router_interface_mac))
|
||||||
|
|
||||||
for i in range(int(self.topo.topo_parameter.get(TopoParameter.SERVER_PATHS))):
|
for i, l in enumerate(self.topo.r2s_server_switches):
|
||||||
cmd = self.interface_up_command(self.get_server_interface(0, i), self.get_server_ip(i), netmask)
|
cmd = self.interface_up_command(self.get_server_interface(0, i), self.get_server_ip(i), netmask)
|
||||||
self.topo.command_to(self.server, cmd)
|
self.topo.command_to(self.server, cmd)
|
||||||
server_interface_mac = self.server.intf(self.get_server_interface(0, i)).MAC()
|
server_interface_mac = self.server.intf(self.get_server_interface(0, i)).MAC()
|
||||||
@ -148,15 +208,18 @@ class MultiInterfaceConfig(TopoConfig):
|
|||||||
return "{}{}.0/24".format(self.param.get(TopoParameter.RIGHT_SUBNET), interface_index)
|
return "{}{}.0/24".format(self.param.get(TopoParameter.RIGHT_SUBNET), interface_index)
|
||||||
|
|
||||||
def client_interface_count(self):
|
def client_interface_count(self):
|
||||||
return len(self.topo.client_switches)
|
return len(self.topo.c2r_client_switches)
|
||||||
|
|
||||||
def get_router_interface_to_server(self, switch_index):
|
def server_interface_count(self):
|
||||||
return self.get_router_interface_to_switch(len(self.topo.server_switches) + switch_index)
|
return len(self.topo.r2s_server_switches)
|
||||||
|
|
||||||
|
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):
|
def get_client_interface(self, client_index, interface_index):
|
||||||
return "{}-eth{}".format(self.topo.get_client_name(client_index), interface_index)
|
return "{}-eth{}".format(self.topo.get_client_name(client_index), interface_index)
|
||||||
|
|
||||||
def get_router_interface_to_switch(self, interface_index):
|
def get_router_interface_to_client_switch(self, interface_index):
|
||||||
return "{}-eth{}".format(self.topo.get_router_name(0), interface_index)
|
return "{}-eth{}".format(self.topo.get_router_name(0), interface_index)
|
||||||
|
|
||||||
def get_server_interface(self, server_index, interface_index):
|
def get_server_interface(self, server_index, interface_index):
|
||||||
|
@ -158,10 +158,10 @@ class MultiInterfaceCongConfig(TopoConfig):
|
|||||||
self.topo.command_to(self.router, "arp -s " + self.getCongClientIP(i) + " " + congClientIntfMac)
|
self.topo.command_to(self.router, "arp -s " + self.getCongClientIP(i) + " " + congClientIntfMac)
|
||||||
|
|
||||||
cmd = self.interface_up_command(
|
cmd = self.interface_up_command(
|
||||||
self.get_router_interface_to_switch(i),
|
self.get_router_interface_to_client_switch(i),
|
||||||
self.getRouterIPSwitch(i), netmask)
|
self.getRouterIPSwitch(i), netmask)
|
||||||
self.topo.command_to(self.router, cmd)
|
self.topo.command_to(self.router, cmd)
|
||||||
routerIntfMac = self.router.intf(self.get_router_interface_to_switch(i)).MAC()
|
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)
|
self.topo.command_to(self.client, "arp -s " + self.getRouterIPSwitch(i) + " " + routerIntfMac)
|
||||||
# Don't forget the congestion client
|
# Don't forget the congestion client
|
||||||
self.topo.command_to(self.cong_clients[i], "arp -s " + self.getRouterIPSwitch(i) + " " + routerIntfMac)
|
self.topo.command_to(self.cong_clients[i], "arp -s " + self.getRouterIPSwitch(i) + " " + routerIntfMac)
|
||||||
@ -240,10 +240,10 @@ class MultiInterfaceCongConfig(TopoConfig):
|
|||||||
return len(self.topo.switch)
|
return len(self.topo.switch)
|
||||||
|
|
||||||
def get_router_interface_to_server(self):
|
def get_router_interface_to_server(self):
|
||||||
return self.get_router_interface_to_switch(len(self.topo.switch))
|
return self.get_router_interface_to_client_switch(len(self.topo.switch))
|
||||||
|
|
||||||
def getRouterInterfaceCongServer(self, congID):
|
def getRouterInterfaceCongServer(self, congID):
|
||||||
return self.get_router_interface_to_switch(len(self.topo.switch) + 1 + congID)
|
return self.get_router_interface_to_client_switch(len(self.topo.switch) + 1 + congID)
|
||||||
|
|
||||||
def get_client_interface(self, interfaceID):
|
def get_client_interface(self, interfaceID):
|
||||||
return Topo.CLIENT_NAME + "-eth" + str(interfaceID)
|
return Topo.CLIENT_NAME + "-eth" + str(interfaceID)
|
||||||
@ -251,7 +251,7 @@ class MultiInterfaceCongConfig(TopoConfig):
|
|||||||
def getCongClientInterface(self, interfaceID):
|
def getCongClientInterface(self, interfaceID):
|
||||||
return MultiInterfaceCongConfig.congClientName + str(interfaceID) + "-eth0"
|
return MultiInterfaceCongConfig.congClientName + str(interfaceID) + "-eth0"
|
||||||
|
|
||||||
def get_router_interface_to_switch(self, interfaceID):
|
def get_router_interface_to_client_switch(self, interfaceID):
|
||||||
return Topo.ROUTER_NAME + "-eth" + str(interfaceID)
|
return Topo.ROUTER_NAME + "-eth" + str(interfaceID)
|
||||||
|
|
||||||
def get_server_interface(self):
|
def get_server_interface(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user