From 07cd7cacd37dc267caaa739f6fcf47486c0a8489 Mon Sep 17 00:00:00 2001 From: Benjamin Hesmans Date: Mon, 12 Jan 2015 12:26:54 +0100 Subject: [PATCH] add ECMP like that support ICMP only ex : sudo ./mpPerf.py -t conf/topo/2_ecmp_1 -x conf/xp/1_ping Signed-off-by: Benjamin Hesmans --- src/conf/topo/2_ecmp_1 | 11 +++ src/conf/xp/1_ping | 2 +- src/mpECMPSingleInterfaceConfig.py | 136 +++++++++++++++++++++++++++++ src/mpECMPSingleInterfaceTopo.py | 47 ++++++++++ src/mpParamTopo.py | 2 +- src/mpTopo.py | 2 + src/mpXpRunner.py | 17 +++- 7 files changed, 214 insertions(+), 3 deletions(-) create mode 100644 src/conf/topo/2_ecmp_1 create mode 100644 src/mpECMPSingleInterfaceConfig.py diff --git a/src/conf/topo/2_ecmp_1 b/src/conf/topo/2_ecmp_1 new file mode 100644 index 0000000..f6e5150 --- /dev/null +++ b/src/conf/topo/2_ecmp_1 @@ -0,0 +1,11 @@ +desc:Simple configuration with two para link +leftSubnet:5.5. +rightSubnet:6.6. +midSubnet:zzz +#path_x:delay,queueSize(may be calc),bw +error +path_0:10,15,5 +path_1:20,10,5 +path_2:30,10,5 +path_3:40,10,5 +topoType:ECMPLike diff --git a/src/conf/xp/1_ping b/src/conf/xp/1_ping index d0fceed..9b7a9f7 100644 --- a/src/conf/xp/1_ping +++ b/src/conf/xp/1_ping @@ -1,2 +1,2 @@ xpType:ping -pingCount:10 +pingCount:16 diff --git a/src/mpECMPSingleInterfaceConfig.py b/src/mpECMPSingleInterfaceConfig.py new file mode 100644 index 0000000..10500e8 --- /dev/null +++ b/src/mpECMPSingleInterfaceConfig.py @@ -0,0 +1,136 @@ +from mpConfig import MpConfig +from mpECMPSingleInterfaceTopo import MpECMPSingleInterfaceTopo +from mpParamTopo import MpParamTopo +from mpTopo import MpTopo +from struct import * + +class MpECMPSingleInterfaceConfig(MpConfig): + def __init__(self, topo, param): + MpConfig.__init__(self, topo, param) + + def configureNetwork(self): + self.configureInterfaces() + self.configureRoute() + + def configureRoute(self): + i = 0 + for l in self.topo.routers: + ##todo calculate mask length + cmd = self.getIptableRuleICMP(3, i) + self.topo.commandTo(self.client, cmd) + self.topo.commandTo(self.server, cmd) + + cmd = self.getIpRuleCmd(i) + self.topo.commandTo(self.client, cmd) + self.topo.commandTo(self.server, cmd) + + cmd = self.getDefaultRouteCmd(self.getRouterIPClient(i), + i) + self.topo.commandTo(self.client, cmd) + cmd = self.getDefaultRouteCmd(self.getRouterIPServer(i), + i) + self.topo.commandTo(self.server, cmd) + + i = i + 1 + + ### + cmd = self.addRouteDefaultSimple(self.getRouterIPServer(0)) + self.topo.commandTo(self.server, cmd) + + cmd = self.addRouteDefaultSimple(self.getRouterIPClient(0)) + self.topo.commandTo(self.client, cmd) + + self.topo.commandTo(self.client, "ip route flush cache") + self.topo.commandTo(self.server, "ip route flush cache") + + def getIptableRuleICMP(self, maskLen, id): + s = 'iptables -t mangle -A OUTPUT -m u32 --u32 ' + \ + '"6&0xFF=0x1 && ' + \ + '24&0x' + \ + pack('>I',(maskLen)).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 configureInterfaces(self): + self.client = self.topo.getHost(MpTopo.clientName) + self.server = self.topo.getHost(MpTopo.serverName) + self.routers = [] + i = 0 + netmask = "255.255.255.0" + for l in self.topo.routers: + self.routers.append(self.topo.getHost( + MpTopo.routerNamePrefix + str(i))) + cmd = self.interfaceUpCommand( + self.getRouterInterfaceLSwitch(i), + self.getRouterIPClient(i), netmask) + self.topo.commandTo(self.routers[-1] , cmd) + + cmd = self.interfaceUpCommand( + self.getRouterInterfaceRSwitch(i), + self.getRouterIPServer(i), netmask) + self.topo.commandTo(self.routers[-1] , cmd) + + i = i + 1 + + cmd = self.interfaceUpCommand(self.getClientInterface(0), + self.getClientIP(0), netmask) + self.topo.commandTo(self.client, cmd) + + cmd = self.interfaceUpCommand(self.getServerInterface(), + self.getServerIP(), netmask) + self.topo.commandTo(self.server, cmd) + + def getClientIP(self, interfaceID): + lSubnet = self.param.getParam(MpParamTopo.LSUBNET) + clientIP = lSubnet + str(interfaceID) + ".1" + return clientIP + + def getClientSubnet(self, interfaceID): + lSubnet = self.param.getParam(MpParamTopo.LSUBNET) + clientSubnet = lSubnet + str(interfaceID) + ".0/24" + return clientSubnet + + def getRouterIPClient(self, id): + lSubnet = self.param.getParam(MpParamTopo.LSUBNET) + routerIP = lSubnet + "0." + str(id + 2) + return routerIP + + def getRouterIPServer(self, id): + rSubnet = self.param.getParam(MpParamTopo.RSUBNET) + routerIP = rSubnet + "0." + str(id + 2) + return routerIP + + def getServerIP(self): + rSubnet = self.param.getParam(MpParamTopo.RSUBNET) + serverIP = rSubnet + "0.1" + return serverIP + + def getClientInterfaceCount(self): + return 1 + + def getRouterInterfaceLSwitch(self, id): + return MpTopo.routerNamePrefix + str(id) + "-eth0" + + def getRouterInterfaceRSwitch(self, id): + return MpTopo.routerNamePrefix + str(id) + "-eth1" + + def getClientInterface(self, interfaceID): + return MpTopo.clientName + "-eth" + str(interfaceID) + + def getServerInterface(self): + return MpTopo.serverName + "-eth0" + diff --git a/src/mpECMPSingleInterfaceTopo.py b/src/mpECMPSingleInterfaceTopo.py index e69de29..105f7e6 100644 --- a/src/mpECMPSingleInterfaceTopo.py +++ b/src/mpECMPSingleInterfaceTopo.py @@ -0,0 +1,47 @@ +from mpTopo import MpTopo + +class MpECMPSingleInterfaceTopo(MpTopo): + def __init__(self, topoBuilder, parameterFile): + MpTopo.__init__(self,topoBuilder, parameterFile) + + print("Hello ECMP topo") + + self.client = self.addHost(MpTopo.clientName) + self.server = self.addHost(MpTopo.serverName) + self.lswitch = self.addSwitch(MpTopo.switchNamePrefix + "0") + self.rswitch = self.addSwitch(MpTopo.switchNamePrefix + "1") + + self.addLink( self.client, self.lswitch) + self.addLink( self.server, self.rswitch) + + self.routers = [] + for l in self.topoParam.linkCharacteristics: + self.routers.append(self.addOneRouterPerLink(l)) + print("added : " + self.routers[-1]) + self.addLink(self.lswitch, self.routers[-1]) + self.addLink(self.rswitch, self.routers[-1], **l.asDict()) + + def addOneRouterPerLink(self, link): + return self.addHost(MpTopo.routerNamePrefix + + str(link.id)) + + def __str__(self): + s = "Single if ECMP like env" + """ + i = 0 + n = len(self.topoParam.linkCharacteristics) + for p in self.topoParam.linkCharacteristics: + 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 + diff --git a/src/mpParamTopo.py b/src/mpParamTopo.py index 55143f7..b8e533e 100644 --- a/src/mpParamTopo.py +++ b/src/mpParamTopo.py @@ -19,10 +19,10 @@ class MpParamTopo(MpParam): if k.startswith("path"): tab = self.paramDic[k].split(",") if len(tab) == 3: - i = i + 1 path = MpLinkCharacteristics(i,tab[0], tab[1], tab[2]) self.linkCharacteristics.append(path) + i = i + 1 else: print("Ignored path :") print(self.paramDic[k]) diff --git a/src/mpTopo.py b/src/mpTopo.py index 4c56ba3..f7d5b83 100644 --- a/src/mpTopo.py +++ b/src/mpTopo.py @@ -1,8 +1,10 @@ class MpTopo: mininetBuilder = "mininet" multiIfTopo = "MultiIf" + ECMPLikeTopo = "ECMPLike" topoAttr = "topoType" switchNamePrefix = "s" + routerNamePrefix = "r" clientName = "Client" serverName = "Server" routerName = "Router" diff --git a/src/mpXpRunner.py b/src/mpXpRunner.py index 4ffb207..06c8828 100644 --- a/src/mpXpRunner.py +++ b/src/mpXpRunner.py @@ -3,9 +3,11 @@ from mpParamTopo import MpParamTopo from mpParamXp import MpParamXp from mpMultiInterfaceTopo import MpMultiInterfaceTopo from mpMultiInterfaceConfig import MpMultiInterfaceConfig +from mpECMPSingleInterfaceConfig import MpECMPSingleInterfaceConfig from mpMininetBuilder import MpMininetBuilder from mpExperiencePing import MpExperiencePing from mpExperience import MpExperience +from mpECMPSingleInterfaceTopo import MpECMPSingleInterfaceTopo class MpXpRunner: def __init__(self, builderType, topoParamFile, xpParamFile): @@ -32,13 +34,25 @@ class MpXpRunner: if t == MpTopo.multiIfTopo: self.mpTopo = MpMultiInterfaceTopo(self.topoBuilder, self.topoParam) + elif t == MpTopo.ECMPLikeTopo: + self.mpTopo = MpECMPSingleInterfaceTopo( + self.topoBuilder, + self.topoParam) else: raise Exception("Unfound Topo" + t) print(self.mpTopo) def defConfig(self): - self.mpTopoConfig = MpMultiInterfaceConfig(self.mpTopo, + t = self.topoParam.getParam(MpTopo.topoAttr) + if t == MpTopo.multiIfTopo: + self.mpTopoConfig = MpMultiInterfaceConfig(self.mpTopo, self.topoParam) + elif t == MpTopo.ECMPLikeTopo: + self.mpTopoConfig = MpECMPSingleInterfaceConfig( + self.mpTopo, + self.topoParam) + else: + raise Exception("Unfound Topo" + t) def startTopo(self): self.mpTopo.startNetwork() @@ -49,6 +63,7 @@ class MpXpRunner: if xp == MpExperience.PING: MpExperiencePing(self.xpParam, self.mpTopo, self.mpTopoConfig) + self.mpTopo.getCLI() else: print("Unfound xp type..." + xp)