get rid of policing
Actually, the policing command, while working reasonably, might be too restrictive. The buffer of the router might be never full, and packet losses tend to happen quickly. Instead, we could rely on the shaping with the limit argument of tbf to do the job. However, the tbf command is first and then the netem one. Thanks to the Mininet magics, the sender can completely ignore queue limitations... To solve this, we just keep tbf and netem, but we first introduce netem (with very large buffer) and then tbf. With the delay, there is no more fast path and we see again realistic results.
This commit is contained in:
parent
b3c1c70a3b
commit
ca59fc4f0e
57
core/topo.py
57
core/topo.py
@ -85,12 +85,12 @@ class LinkCharacteristics(object):
|
||||
return "tc qdisc del dev {} root; tc qdisc del dev {} ingress ".format(ifname, ifname)
|
||||
|
||||
def build_bandwidth_cmd(self, ifname, change=False):
|
||||
return "tc qdisc {} dev {} root handle 5:0 tbf rate {}mbit burst 15000 limit {}".format(
|
||||
"change" if change else "add", ifname, self.bandwidth, self.buffer_size())
|
||||
return "tc qdisc {} dev {} root handle 1:0 tbf rate {}mbit burst 15000 limit {}".format(#; tc qdisc {} dev {} parent 1:0 bfifo limit {}".format(
|
||||
"change" if change else "add", ifname, self.bandwidth, self.buffer_size())#, "change" if change else "add", ifname, self.buffer_size())
|
||||
|
||||
def build_changing_bandwidth_cmd(self, ifname):
|
||||
return "&& ".join(
|
||||
["sleep {} && {} ".format(
|
||||
["sleep {} && ({}) ".format(
|
||||
n.delta, self.build_bandwidth_cmd(ifname, change=True)) for n in self.netem_at]
|
||||
+ ["true &"]
|
||||
)
|
||||
@ -106,19 +106,6 @@ class LinkCharacteristics(object):
|
||||
+ ["true &"]
|
||||
)
|
||||
|
||||
def build_policing_cmd(self, ifname, change=False):
|
||||
return "tc qdisc {} dev {} handle ffff: ingress ; \
|
||||
tc filter {} dev {} parent ffff: u32 match u32 0 0 police rate {}mbit burst {} drop".format(
|
||||
"change" if change else "add", ifname, "change" if change else "add", ifname,
|
||||
self.bandwidth, int(self.buffer_size()) * 1.2)
|
||||
|
||||
def build_changing_policing_cmd(self, ifname):
|
||||
return "&& ".join(
|
||||
["sleep {} && ({}) ".format(
|
||||
n.delta, self.build_policing_cmd(ifname, change=True)) for n in self.netem_at]
|
||||
+ ["true &"]
|
||||
)
|
||||
|
||||
def as_dict(self):
|
||||
"""
|
||||
Notably used by BottleneckLink
|
||||
@ -320,36 +307,27 @@ class BottleneckLink(object):
|
||||
self.topo.command_to(self.bs2, clean_cmd)
|
||||
|
||||
# Flow bs0 -> bs3
|
||||
policing_cmd = self.link_characteristics.build_policing_cmd(bs1_interface_names[0])
|
||||
logging.info(policing_cmd)
|
||||
self.topo.command_to(self.bs1, policing_cmd)
|
||||
shaping_cmd = self.link_characteristics.build_bandwidth_cmd(bs1_interface_names[-1])
|
||||
logging.info(shaping_cmd)
|
||||
self.topo.command_to(self.bs1, shaping_cmd)
|
||||
netem_cmd = self.link_characteristics.build_netem_cmd(bs2_interface_names[-1],
|
||||
"loss {}".format(self.link_characteristics.loss) if float(self.link_characteristics.loss) > 0 else "")
|
||||
logging.info(netem_cmd)
|
||||
self.topo.command_to(self.bs2, netem_cmd)
|
||||
|
||||
# Flow bs3 -> bs0
|
||||
policing_cmd = self.link_characteristics.build_policing_cmd(bs2_interface_names[-1])
|
||||
logging.info(policing_cmd)
|
||||
self.topo.command_to(self.bs2, policing_cmd)
|
||||
shaping_cmd = self.link_characteristics.build_bandwidth_cmd(bs2_interface_names[0])
|
||||
logging.info(shaping_cmd)
|
||||
self.topo.command_to(self.bs2, shaping_cmd)
|
||||
netem_cmd = self.link_characteristics.build_netem_cmd(bs1_interface_names[0],
|
||||
netem_cmd = self.link_characteristics.build_netem_cmd(bs1_interface_names[-1],
|
||||
"loss {}".format(self.link_characteristics.loss) if float(self.link_characteristics.loss) > 0 else "")
|
||||
logging.info(netem_cmd)
|
||||
self.topo.command_to(self.bs1, netem_cmd)
|
||||
shaping_cmd = self.link_characteristics.build_bandwidth_cmd(bs2_interface_names[-1])
|
||||
logging.info(shaping_cmd)
|
||||
self.topo.command_to(self.bs2, shaping_cmd)
|
||||
|
||||
# Flow bs3 -> bs0
|
||||
netem_cmd = self.link_characteristics.build_netem_cmd(bs2_interface_names[0],
|
||||
"loss {}".format(self.link_characteristics.loss) if float(self.link_characteristics.loss) > 0 else "")
|
||||
logging.info(netem_cmd)
|
||||
self.topo.command_to(self.bs2, netem_cmd)
|
||||
shaping_cmd = self.link_characteristics.build_bandwidth_cmd(bs1_interface_names[0])
|
||||
logging.info(shaping_cmd)
|
||||
self.topo.command_to(self.bs1, shaping_cmd)
|
||||
|
||||
def configure_changing_bottleneck(self):
|
||||
bs1_interface_names = self.topo.get_interface_names(self.bs1)
|
||||
bs2_interface_names = self.topo.get_interface_names(self.bs2)
|
||||
# Flow bs0 -> bs3
|
||||
policing_cmd = self.link_characteristics.build_changing_policing_cmd(bs1_interface_names[0])
|
||||
logging.info(policing_cmd)
|
||||
self.topo.command_to(self.bs1, policing_cmd)
|
||||
shaping_cmd = self.link_characteristics.build_changing_bandwidth_cmd(bs1_interface_names[-1])
|
||||
logging.info(shaping_cmd)
|
||||
self.topo.command_to(self.bs1, shaping_cmd)
|
||||
@ -358,9 +336,6 @@ class BottleneckLink(object):
|
||||
self.topo.command_to(self.bs2, netem_cmd)
|
||||
|
||||
# Flow bs3 -> bs0
|
||||
policing_cmd = self.link_characteristics.build_changing_policing_cmd(bs2_interface_names[-1])
|
||||
logging.info(policing_cmd)
|
||||
self.topo.command_to(self.bs2, policing_cmd)
|
||||
shaping_cmd = self.link_characteristics.build_changing_bandwidth_cmd(bs2_interface_names[0])
|
||||
logging.info(shaping_cmd)
|
||||
self.topo.command_to(self.bs2, shaping_cmd)
|
||||
|
Loading…
Reference in New Issue
Block a user