mininet-sample/mpExperience.py
2020-07-13 09:50:41 +02:00

280 lines
11 KiB
Python

from mpParamXp import MpParamXp
from mpMultiInterfaceTopo import MpMultiInterfaceTopo
class MpExperience:
PING = "ping"
NCPV = "ncpv"
NC = "nc"
NONE = "none"
HTTPS = "https"
HTTP = "http"
EPLOAD = "epload"
NETPERF = "netperf"
AB = "ab"
SIRI = "siri"
SENDFILE = "sendfile"
VLC = "vlc"
IPERF = "iperf"
DITG = "ditg"
MSG = "msg"
SIRIHTTP = "sirihttp"
SIRIMSG = "sirimsg"
QUIC = "quic"
QUICSIRI = "quicsiri"
def __init__(self, xpParam, mpTopo, mpConfig):
self.xpParam = xpParam
self.mpTopo = mpTopo
self.mpConfig = mpConfig
print(self.xpParam)
def classicRun(self):
self.prepare()
self.run()
self.clean()
def prepare(self):
self.setupSysctl()
self.runUserspacePM()
self.mpConfig.configureNetwork()
self.changeMetric()
self.putPriorityOnPaths()
self.disableTSO()
self.runTcpDump()
self.runNetemAt()
pass
def changeMetric(self):
metric = self.xpParam.getParam(MpParamXp.METRIC)
if int(metric) >= 0:
self.mpTopo.notNSCommand("echo " + metric + " > /sys/module/mptcp_sched_metric/parameters/metric")
def putPriorityOnPaths(self):
# Only meaningful if mpTopo is instance of MpMultiInterfaceTopo
if isinstance(self.mpTopo, MpMultiInterfaceTopo):
prioPath0 = self.xpParam.getParam(MpParamXp.PRIOPATH0)
prioPath1 = self.xpParam.getParam(MpParamXp.PRIOPATH1)
if not prioPath0 == prioPath1:
self.mpTopo.commandTo(self.mpConfig.client, "/home/mininet/iproute/ip/ip link set dev " +
self.mpConfig.getClientInterface(0) + " priority " + str(prioPath0))
self.mpTopo.commandTo(self.mpConfig.router, "/home/mininet/iproute/ip/ip link set dev " +
self.mpConfig.getRouterInterfaceSwitch(0) + " priority " +
str(prioPath0))
self.mpTopo.commandTo(self.mpConfig.client, "/home/mininet/iproute/ip/ip link set dev " +
self.mpConfig.getClientInterface(1) + " priority " + str(prioPath1))
self.mpTopo.commandTo(self.mpConfig.router, "/home/mininet/iproute/ip/ip link set dev " +
self.mpConfig.getRouterInterfaceSwitch(1) + " priority " +
str(prioPath1))
backupPath0 = self.xpParam.getParam(MpParamXp.BACKUPPATH0)
if int(backupPath0) > 0:
self.mpTopo.commandTo(self.mpConfig.client, self.mpConfig.interfaceBUPCommand(self.mpConfig.getClientInterface(0)))
self.mpTopo.commandTo(self.mpConfig.router, self.mpConfig.interfaceBUPCommand(self.mpConfig.getRouterInterfaceSwitch(0)))
backupPath1 = self.xpParam.getParam(MpParamXp.BACKUPPATH1)
if int(backupPath1) > 0:
self.mpTopo.commandTo(self.mpConfig.client, self.mpConfig.interfaceBUPCommand(self.mpConfig.getClientInterface(1)))
self.mpTopo.commandTo(self.mpConfig.router, self.mpConfig.interfaceBUPCommand(self.mpConfig.getRouterInterfaceSwitch(1)))
def disableTSO(self):
links = self.mpTopo.getLinkCharacteristics()
i = 0
for l in links:
lname = self.mpConfig.getMidLeftName(i)
rname = self.mpConfig.getMidRightName(i)
lbox = self.mpTopo.getHost(lname)
lif = self.mpConfig.getMidL2RInterface(i)
rif = self.mpConfig.getMidR2LInterface(i)
rbox = self.mpTopo.getHost(rname)
print(str(lname) + " " + str(lif))
print(str(rname) + " " + str(rif))
print("boxes " + str(lbox) + " " + str(rbox))
cmd = "ethtool -K " + lif + " tso off"
print(cmd)
self.mpTopo.commandTo(lbox, cmd)
cmd = "ethtool -K " + rif + " tso off"
print(cmd)
self.mpTopo.commandTo(rbox, cmd)
i = i + 1
# And for the server
cmd = "ethtool -K " + self.mpConfig.getServerInterface() + " tso off"
print(cmd)
self.mpTopo.commandTo(self.mpConfig.server, cmd)
cmd = "ethtool -K " + self.mpConfig.getRouterInterfaceSwitch(self.mpConfig.getClientInterfaceCount()) + " tso off"
print(cmd)
self.mpTopo.commandTo(self.mpConfig.router, cmd)
def runUserspacePM(self):
if self.xpParam.getParam(MpParamXp.KERNELPMC) != "netlink":
print("Client : Error, I can't change the userspace pm if the kernel pm is not netlink !")
else:
upmc = self.xpParam.getParam(MpParamXp.USERPMC)
upmca = self.xpParam.getParam(MpParamXp.USERPMCARGS)
self.mpTopo.commandTo(self.mpConfig.client, upmc + \
" " + upmca + " &>upmc.log &")
if self.xpParam.getParam(MpParamXp.KERNELPMS) != "netlink":
print("Server : Error, I can't change the userspace pm if the kernel pm is not netlink !")
else:
upms = self.xpParam.getParam(MpParamXp.USERPMS)
upmsa = self.xpParam.getParam(MpParamXp.USERPMSARGS)
self.mpTopo.commandTo(self.mpConfig.server, upms + \
" " + upmsa + " &>upms.log &")
def cleanUserspacePM(self):
if self.xpParam.getParam(MpParamXp.KERNELPMC) != "netlink":
print("Client : Error, I can't change the userspace pm if the kernel pm is not netlink !")
else:
upmc = self.xpParam.getParam(MpParamXp.USERPMC)
self.mpTopo.commandTo(self.mpConfig.client, "killall " + upmc)
if self.xpParam.getParam(MpParamXp.KERNELPMS) != "netlink":
print("Server : Error, I can't change the userspace pm if the kernel pm is not netlink !")
else:
upms = self.xpParam.getParam(MpParamXp.USERPMS)
self.mpTopo.commandTo(self.mpConfig.server, "killall " + upms)
def runNetemAt(self):
if not self.mpTopo.changeNetem == "yes":
print("I don't need to change netem")
return
print("Will change netem config on the fly")
links = self.mpTopo.getLinkCharacteristics()
i = 0
for l in links:
lname = self.mpConfig.getMidLeftName(i)
rname = self.mpConfig.getMidRightName(i)
lbox = self.mpTopo.getHost(lname)
lif = self.mpConfig.getMidL2RInterface(i)
rif = self.mpConfig.getMidR2LInterface(i)
rbox = self.mpTopo.getHost(rname)
print(str(lname) + " " + str(lif))
print(str(rname) + " " + str(rif))
print("boxes " + str(lbox) + " " + str(rbox))
cmd = l.buildBwCmd(lif)
print(cmd)
self.mpTopo.commandTo(lbox, cmd)
cmd = l.buildBwCmd(rif)
print(cmd)
self.mpTopo.commandTo(rbox, cmd)
ilif = self.mpConfig.getMidL2RIncomingInterface(i)
irif = self.mpConfig.getMidR2LIncomingInterface(i)
cmd = l.buildPolicingCmd(ilif)
print(cmd)
self.mpTopo.commandTo(lbox, cmd)
cmd = l.buildPolicingCmd(irif)
print(cmd)
self.mpTopo.commandTo(rbox, cmd)
cmd = l.buildNetemCmd(irif)
print(cmd)
self.mpTopo.commandTo(rbox, cmd)
cmd = l.buildNetemCmd(ilif)
print(cmd)
self.mpTopo.commandTo(lbox, cmd)
i = i + 1
def run(self):
pass
def clean(self):
self.mpTopo.commandTo(self.mpConfig.client,
"killall tcpdump")
self.mpTopo.commandTo(self.mpConfig.server,
"killall tcpdump")
self.backUpSysctl()
self.cleanUserspacePM()
pass
def setupSysctl(self):
self.saveSysctl()
self.writeSysctl()
def saveSysctl(self):
self.sysctlBUP = {}
self._saveSysctl(MpParamXp.sysctlKey, self.sysctlBUP)
self.sysctlBUPC = {}
self._saveSysctl(MpParamXp.sysctlKeyClient, self.sysctlBUPC,
ns = True, who = self.mpConfig.client)
self.sysctlBUPS = {}
self._saveSysctl(MpParamXp.sysctlKeyServer, self.sysctlBUPS,
ns = True, who = self.mpConfig.server)
def _saveSysctl(self, sysctlDic, sysctlBUP, ns = False, who = None):
for k in sysctlDic:
sysctlKey = sysctlDic[k]
cmd = self.cmdReadSysctl(sysctlKey)
if not ns:
val = self.mpTopo.notNSCommand(cmd)
else:
val = self.mpTopo.commandTo(who, cmd)
if val == "Error":
print("oooops can't get sysctl " + sysctlKey)
else:
sysctlBUP[k] = val.split(" ",2)[2][:-1]
def cmdReadSysctl(self, key):
s = "sysctl " + key
return s
def cmdWriteSysctl(self, key, value):
s = self.cmdReadSysctl(key)
s = s + "=\"" + str(value) + "\""
return s
def writeSysctl(self):
self._writeSysctl(MpParamXp.sysctlKey, self.sysctlBUP)
self._writeSysctl(MpParamXp.sysctlKeyClient, self.sysctlBUPC,
ns = True, who = self.mpConfig.client)
self._writeSysctl(MpParamXp.sysctlKeyServer, self.sysctlBUPS,
ns = True, who = self.mpConfig.server)
def _writeSysctl(self, sysctlDic, sysctlBUP, ns = False, who = None):
for k in sysctlBUP:
sysctlKey = sysctlDic[k]
sysctlValue = self.xpParam.getParam(k)
cmd = self.cmdWriteSysctl(sysctlKey,sysctlValue)
if not ns:
val = self.mpTopo.notNSCommand(cmd)
else:
val = self.mpTopo.commandTo(who, cmd)
if val == "Error":
print("oooops can't set sysctl " + sysctlKey)
def backUpSysctl(self):
self._backUpSysctl(MpParamXp.sysctlKey, self.sysctlBUP)
self._backUpSysctl(MpParamXp.sysctlKeyClient, self.sysctlBUPC,
ns = True, who = self.mpConfig.client)
self._backUpSysctl(MpParamXp.sysctlKeyServer, self.sysctlBUPS,
ns = True, who = self.mpConfig.server)
def _backUpSysctl(self, sysctlDic, sysctlBUP, ns = False, who = None):
for k in sysctlBUP:
sysctlKey = sysctlDic[k]
sysctlValue = sysctlBUP[k]
cmd = self.cmdWriteSysctl(sysctlKey,sysctlValue)
if not ns:
val = self.mpTopo.notNSCommand(cmd)
else:
val = self.mpTopo.commandTo(who, cmd)
if val == "Error":
print("oooops can't set sysctl " + sysctlKey)
def runTcpDump(self):
#todo : replace filename by cst
cpcap = self.xpParam.getParam(MpParamXp.CLIENTPCAP)
spcap = self.xpParam.getParam(MpParamXp.SERVERPCAP)
snaplenpcap = self.xpParam.getParam(MpParamXp.SNAPLENPCAP)
if cpcap == "yes" :
self.mpTopo.commandTo(self.mpConfig.client,
"tcpdump -i any -s " + snaplenpcap + " -w client.pcap &")
if spcap == "yes" :
self.mpTopo.commandTo(self.mpConfig.server,
"tcpdump -i any -s " + snaplenpcap + " -w server.pcap &")
if spcap == "yes" or cpcap == "yes":
self.mpTopo.commandTo(self.mpConfig.client,"sleep 5")