def setup(self, nameToSwtichMap):
     '''
     This function setup all the relevant stuffs for running the algorithm
     '''
     startingRankForTestingTopKPathProblem = 0
     #swUtils.setupFlowtypeBasedIngressRateMonitoringForKPathProblem(self.p4dev)
     self.initMAT(self.p4dev, ConfConst.K)
     if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
         i = 0
         for k in self.p4dev.portToSpineSwitchMap.keys():
             pkt = self.topKPathManager.insertPort(
                 port=int(k), k=startingRankForTestingTopKPathProblem)
             self.p4dev.send_already_built_control_packet_for_top_k_path(
                 pkt)
             i = i + 1
     elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
         for k in self.p4dev.portToSuperSpineSwitchMap.keys():
             pkt = self.topKPathManager.insertPort(port=int(k), k=int(k))
             self.p4dev.send_already_built_control_packet_for_top_k_path(
                 pkt)
     elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
         self.topKPathManager = TopKPathManager(dev=self.p4dev,
                                                k=ConfConst.K)
         pass
     # self.x = threading.Thread(target=self.topKpathroutingTesting, args=())
     # self.x.start()
     # logger.info("TopKpathroutingTesting thread started")
     return
    def setup(self,nameToSwitchMap):
        '''
        This function setup all the relevant stuffs for running the algorithm
        '''
        startingRankForTestingTopKPathProblem = 0
        #swUtils.setupFlowtypeBasedIngressRateMonitoringForKPathProblem(self.p4dev)
        self.initMAT(self.p4dev, ConfConst.K)
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            rankOrder = [4,6,8] # best 4 paths will be in rank 0, then 2 in next rank and so on
            portList = list(self.p4dev.portToSpineSwitchMap.keys())
            i=0
            while i < len(portList):
                for r in range(0,len(rankOrder)):
                    if i < rankOrder[r]:
                        port = portList[i]
                        insertPkt = self.topKPathManager.insertPort(port, r)
                        self.p4dev.send_already_built_control_packet_for_top_k_path(insertPkt)
                i = i+1
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            rankOrder = [4,6,8] # best 4 paths will be in rank 0, then 2 in next rank and so on
            portList = list(self.p4dev.portToSuperSpineSwitchMap.keys())
            i=0
            while i < len(portList):
                for r in range(0,len(rankOrder)):
                    if i < rankOrder[r]:
                        port = portList[i]
                        insertPkt = self.topKPathManager.insertPort(port, r)
                        self.p4dev.send_already_built_control_packet_for_top_k_path(insertPkt)
                i = i+1
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(dev = self.p4dev, k=ConfConst.K) # by default add space for 16 ports in super spine. This is not actually used in our simulation
            pass

        return
Example #3
0
 def setup(self, nameToSwitchMap
           ):  #This one initially setup three path in same rank
     '''
     This function setup all the relevant stuffs for running the algorithm
     '''
     startingRankForTestingTopKPathProblem = 0
     self.initMAT(self.p4dev, ConfConst.K)
     if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
         for k in self.p4dev.portToSpineSwitchMap.keys():
             if (k in ConfigConst.reservedPortList) and (
                 (ConfigConst.specialTunnelStartingSwitch
                  in self.p4dev.devName) or
                 (ConfigConst.specialTunnelEndingSwitch
                  in self.p4dev.devName)):
                 continue
             else:
                 pkt = self.topKPathManager.insertPort(
                     port=int(k), k=startingRankForTestingTopKPathProblem)
                 self.p4dev.send_already_built_control_packet_for_top_k_path(
                     pkt)
         i = 0
         while i < len(ConfigConst.reservedPortList):
             pkt = self.topKPathManager.insertPort(
                 port=int(ConfigConst.reservedPortList[i]),
                 k=ConfigConst.reservedRanks[i])
             self.p4dev.send_already_built_control_packet_for_top_k_path(
                 pkt)
             i = i + 1
     elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
         for k in self.p4dev.portToSuperSpineSwitchMap.keys():
             if (k in ConfigConst.reservedPortList):
                 continue
             else:
                 pkt = self.topKPathManager.insertPort(
                     port=int(k), k=startingRankForTestingTopKPathProblem)
                 self.p4dev.send_already_built_control_packet_for_top_k_path(
                     pkt)
     elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
         self.topKPathManager = TopKPathManager(
             dev=self.p4dev, k=ConfConst.K
         )  # by default add space for 16 ports in super spine. This is not actually used in our simulation
         pass
     if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
         self.link_reconfiguration_thread = threading.Thread(
             target=self.linkReconfigurator, args=())
         self.link_reconfiguration_thread.start()
         logger.info("TopKpathrouting link_reconfiguration_thread  started")
     #else we do not need this process for spine switches because we are simulatin only layer 2 fat tree
     return
    def setupOld(
        self, nameToSwitchMap
    ):  #This one initially setup three path in three different ranks
        '''
        This function setup all the relevant stuffs for running the algorithm
        '''
        self.p4dev.setupECMPUpstreamRouting()
        startingRankForTestingTopKPathProblem = 0
        #swUtils.setupFlowtypeBasedIngressRateMonitoringForKPathProblem(self.p4dev)
        self.initMAT(self.p4dev, ConfConst.K)
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            i = 0
            for k in self.p4dev.portToSpineSwitchMap.keys():
                if (k in ConfigConst.reservedPortList) and (
                    (ConfigConst.specialTunnelStartingSwitch
                     in self.p4dev.devName) or
                    (ConfigConst.specialTunnelEndingSwitch
                     in self.p4dev.devName)):
                    continue
                else:
                    pkt = self.topKPathManager.insertPort(port=int(k), k=i)
                    self.p4dev.send_already_built_control_packet_for_top_k_path(
                        pkt)
                    i = i + 1
            i = 0
            while i < len(ConfigConst.reservedPortList):
                pkt = self.topKPathManager.insertPort(
                    port=int(ConfigConst.reservedPortList[i]),
                    k=ConfigConst.reservedRanks[i])
                self.p4dev.send_already_built_control_packet_for_top_k_path(
                    pkt)
                i = i + 1
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            for k in self.p4dev.portToSuperSpineSwitchMap.keys():
                if (k in ConfigConst.reservedPortList):
                    continue
                else:
                    pkt = self.topKPathManager.insertPort(
                        port=int(k), k=startingRankForTestingTopKPathProblem)
                    self.p4dev.send_already_built_control_packet_for_top_k_path(
                        pkt)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(
                dev=self.p4dev, k=ConfConst.K
            )  # by default add space for 16 ports in super spine. This is not actually used in our simulation
            pass

        return
Example #5
0
    def __init__(self, dev):
        self.p4dev = dev
        self.testOperationIndex = 0
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            #self.topKPathManager = TopKPathManager(dev = self.p4dev, k=len(self.p4dev.portToSpineSwitchMap.keys()))
            self.topKPathManager = TopKPathManager(dev=self.p4dev,
                                                   k=ConfConst.K)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            # self.topKPathManager = TopKPathManager(dev = self.p4dev, k=len(self.p4dev.portToSuperSpineSwitchMap.keys()))
            self.topKPathManager = TopKPathManager(dev=self.p4dev,
                                                   k=ConfConst.K)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(
                dev=self.p4dev, k=ConfConst.K
            )  # by default add space for 16 ports in super spine. This is not actually used in our simulation
            pass

        return
class TopKPathRouting:
    def __init__(self, dev):
        self.p4dev = dev
        self.testOperationIndex = 0
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            #self.topKPathManager = TopKPathManager(dev = self.p4dev, k=len(self.p4dev.portToSpineSwitchMap.keys()))
            self.topKPathManager = TopKPathManager(dev=self.p4dev, k=16)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            # self.topKPathManager = TopKPathManager(dev = self.p4dev, k=len(self.p4dev.portToSuperSpineSwitchMap.keys()))
            self.topKPathManager = TopKPathManager(dev=self.p4dev, k=16)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(
                dev=self.p4dev, k=16
            )  # by default add space for 16 ports in super spine. This is not actually used in our simulation
            pass

        return

    def initMAT(self, switchObject, bitMaskLength):
        allOneMAsk = BinaryMask(bitMaskLength)
        allOneMAsk.setAllBitOne()
        allOneMAskBinaryString = allOneMAsk.getBinaryString()
        for j in range(0, bitMaskLength):
            mask = BinaryMask(bitMaskLength)
            mask.setNthBitWithB(n=j, b=1)
            maskAsString = mask.getBinaryString()
            switchObject.addTernaryMatchEntry(
                "IngressPipeImpl.k_path_selector_control_block.best_path_finder_mat",
                fieldName="local_metadata.best_path_selector_bitmask",
                fieldValue=allOneMAskBinaryString,
                mask=maskAsString,
                actionName=
                "IngressPipeImpl.k_path_selector_control_block.best_path_finder_action_with_param",
                actionParamName="rank",
                actionParamValue=str(j),
                priority=bitMaskLength - j + 1)

    def setup(self, nameToSwtichMap):
        '''
        This function setup all the relevant stuffs for running the algorithm
        '''
        startingRankForTestingTopKPathProblem = 0
        #swUtils.setupFlowtypeBasedIngressRateMonitoringForKPathProblem(self.p4dev)
        self.initMAT(self.p4dev, ConfConst.K)
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            i = 0
            for k in self.p4dev.portToSpineSwitchMap.keys():
                pkt = self.topKPathManager.insertPort(
                    port=int(k), k=startingRankForTestingTopKPathProblem)
                self.p4dev.send_already_built_control_packet_for_top_k_path(
                    pkt)
                i = i + 1
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            for k in self.p4dev.portToSuperSpineSwitchMap.keys():
                pkt = self.topKPathManager.insertPort(port=int(k), k=int(k))
                self.p4dev.send_already_built_control_packet_for_top_k_path(
                    pkt)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(dev=self.p4dev,
                                                   k=ConfConst.K)
            pass
        # self.x = threading.Thread(target=self.topKpathroutingTesting, args=())
        # self.x.start()
        # logger.info("TopKpathroutingTesting thread started")
        return

    def processFeedbackPacket(self, parsedPkt, dev):
        #print("Called the algo")
        #TODO: for each of the different types of the packet, we have to write a separate function to process them

        pass

    def testPerRankMaxPortCapacity(self):
        for i in range(1, 25):
            pkt = self.topKPathManager.insertPort(port=int(i), k=10)
            self.p4dev.send_already_built_control_packet_for_top_k_path(pkt)
        for i in range(50, 75):
            pkt = self.topKPathManager.insertPort(port=int(i), k=0)
            self.p4dev.send_already_built_control_packet_for_top_k_path(pkt)

    # for k in range(0,len(portCfg)): # k gives the rank iteslf as the port configs are already sorted
    #     dltPkt = self.topKPathManager.deletePort(portCfg[k][0])
    #     self.p4dev.send_already_built_control_packet_for_top_k_path(dltPkt)
    #     if(float(portCfg[k][1]) > 0): # if 0 that means the port is not down . So need to iinsert it. but for rate < 0 we delete the port but do not insert it agian to simulate delete behavior
    #         insertPkt = self.topKPathManager.insertPort(portCfg[k][0], k)
    #         self.p4dev.send_already_built_control_packet_for_top_k_path(insertPkt)
    #     #Reconfigure the port rate and buffer length

    def topKpathroutingTesting(self):
        time.sleep(35)
        topologyConfigFilePath = ConfConst.TOPOLOGY_CONFIG_FILE
        # if(self.p4dev.devName == "device:p0l0"):
        #     testEvaluator = TestCommandDeployer(topologyConfigFilePath,
        #                                         "/home/deba/Desktop/Top-K-Path/testAndMeasurement/TestConfigs/topKPath/l2strideSmallLarge-highRationForLargeFlows.json",
        #                                         ConfConst.IPERF3_CLIENT_PORT_START, ConfConst.IPERF3_SERVER_PORT_START, testStartDelay= 20)
        #     testEvaluator.setupTestCase()
        i = 0
        while (True):
            j = i % len(tstConst.PORT_RATE_CONFIGS)
            if (self.p4dev.devName != "device:p0l0"):
                time.sleep(tstConst.RECONFIGURATION_GAP)
                return
            portCfg = tstConst.PORT_RATE_CONFIGS[j]
            for k in range(
                    0, len(portCfg)
            ):  # k gives the rank iteslf as the port configs are already sorted
                if self.p4dev.fabric_device_config.switch_type == InternalConfig.SwitchType.LEAF:
                    port = portCfg[k][0]
                    portRate = int(
                        self.p4dev.queueRateForSpineFacingPortsOfLeafSwitch *
                        portCfg[k][1])
                    bufferSize = int(
                        portRate * ConfConst.QUEUE_RATE_TO_QUEUE_DEPTH_FACTOR)
                    setPortQueueRatesAndDepth(self.p4dev, port, portRate,
                                              bufferSize)
                if self.p4dev.fabric_device_config.switch_type == InternalConfig.SwitchType.SPINE:
                    port = portCfg[k][0]
                    portRate = int(
                        self.p4dev.
                        queueRateForSuperSpineSwitchFacingPortsOfSpineSwitch *
                        portCfg[k][1])
                    bufferSize = int(
                        portRate * ConfConst.QUEUE_RATE_TO_QUEUE_DEPTH_FACTOR)
                    setPortQueueRatesAndDepth(self.p4dev, port, portRate,
                                              bufferSize)
                dltPkt = self.topKPathManager.deletePort(portCfg[k][0])
                self.p4dev.send_already_built_control_packet_for_top_k_path(
                    dltPkt)
                if (
                        float(portCfg[k][1]) > 0
                ):  # if 0 that means the port is not down . So need to iinsert it. but for rate < 0 we delete the port but do not insert it agian to simulate delete behavior
                    insertPkt = self.topKPathManager.insertPort(
                        portCfg[k][0], k)
                    self.p4dev.send_already_built_control_packet_for_top_k_path(
                        insertPkt)

            i = i + 1
            time.sleep(tstConst.RECONFIGURATION_GAP)
class TopKPathRouting:

    def __init__(self, dev):
        self.p4dev = dev
        self.testOperationIndex =0
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            #self.topKPathManager = TopKPathManager(dev = self.p4dev, k=len(self.p4dev.portToSpineSwitchMap.keys()))
            self.topKPathManager = TopKPathManager(dev = self.p4dev, k=ConfConst.K)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            # self.topKPathManager = TopKPathManager(dev = self.p4dev, k=len(self.p4dev.portToSuperSpineSwitchMap.keys()))
            self.topKPathManager = TopKPathManager(dev = self.p4dev, k=ConfConst.K)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(dev = self.p4dev, k=ConfConst.K) # by default add space for 16 ports in super spine. This is not actually used in our simulation
            pass

        return
    def initMAT(self, switchObject, bitMaskLength):
        allOneMAsk = BinaryMask(bitMaskLength)
        allOneMAsk.setAllBitOne()
        allOneMAskBinaryString = allOneMAsk.getBinaryString()
        for j in range(0, bitMaskLength):
            mask = BinaryMask(bitMaskLength)
            mask.setNthBitWithB(n=j,b=1)
            maskAsString = mask.getBinaryString()
            switchObject.addTernaryMatchEntry( "IngressPipeImpl.k_path_selector_control_block.kth_path_finder_mat",
                                               fieldName = "local_metadata.kth_path_selector_bitmask",
                                               fieldValue = allOneMAskBinaryString, mask = maskAsString,
                                               actionName = "IngressPipeImpl.k_path_selector_control_block.kth_path_finder_action_with_param",
                                               actionParamName = "rank",
                                               actionParamValue = str(j), priority=bitMaskLength-j+1)





    def setup(self,nameToSwitchMap):
        '''
        This function setup all the relevant stuffs for running the algorithm
        '''
        startingRankForTestingTopKPathProblem = 0
        #swUtils.setupFlowtypeBasedIngressRateMonitoringForKPathProblem(self.p4dev)
        self.initMAT(self.p4dev, ConfConst.K)
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            rankOrder = [4,6,8] # best 4 paths will be in rank 0, then 2 in next rank and so on
            portList = list(self.p4dev.portToSpineSwitchMap.keys())
            i=0
            while i < len(portList):
                for r in range(0,len(rankOrder)):
                    if i < rankOrder[r]:
                        port = portList[i]
                        insertPkt = self.topKPathManager.insertPort(port, r)
                        self.p4dev.send_already_built_control_packet_for_top_k_path(insertPkt)
                i = i+1
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            rankOrder = [4,6,8] # best 4 paths will be in rank 0, then 2 in next rank and so on
            portList = list(self.p4dev.portToSuperSpineSwitchMap.keys())
            i=0
            while i < len(portList):
                for r in range(0,len(rankOrder)):
                    if i < rankOrder[r]:
                        port = portList[i]
                        insertPkt = self.topKPathManager.insertPort(port, r)
                        self.p4dev.send_already_built_control_packet_for_top_k_path(insertPkt)
                i = i+1
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(dev = self.p4dev, k=ConfConst.K) # by default add space for 16 ports in super spine. This is not actually used in our simulation
            pass

        return

    def processFeedbackPacket(self, parsedPkt, dev):
        #print("Called the algo")
        #TODO: for each of the different types of the packet, we have to write a separate function to process them
        pass

    def p4kpUtilBasedReconfigureForLeafSwitches(self, linkUtilStats, oldLinkUtilStats):
        # logger.info("CLB ALGORITHM: For switch "+ self.p4dev.devName+ "new Utilization data is  "+str(linkUtilStats))
        # logger.info("CLB ALGORITHM: For switch "+ self.p4dev.devName+ "old Utilization data is  "+str(oldLinkUtilStats))
        pathAndUtilist = []
        for i in range (int(ConfConst.MAX_PORTS_IN_SWITCH/2), ConfConst.MAX_PORTS_IN_SWITCH):
            index = i
            utilInLastInterval = (linkUtilStats[index] -  oldLinkUtilStats[index])/ConfigConst.queueRateForSpineFacingPortsOfLeafSwitch
            # rankInLastInterval = self.topKPathManager.portToRankMap.get(i)
            # pathAndUtilist.append((i,utilInLastInterval,rankInLastInterval))
            pathAndUtilist.append((i+1,utilInLastInterval))
        pathAndUtilist.sort(key=lambda x:x[1])
        # if(self.p4dev.devName == ConfConst.CLB_TESTER_DEVICE_NAME):
        #     print("For device "+self.p4dev.devName+" The port utilization data according to rank is "+str(pathAndUtilist))
        controlPacketList = []
        portConfiguredIncurrentIteration = {}
        for i in range (0, len(pathAndUtilist)):
            port = pathAndUtilist[i][0]
            if(portConfiguredIncurrentIteration.get(port)== None):
                dltPkt = self.topKPathManager.deletePort(port)
                controlPacketList.append(dltPkt)
                # self.p4dev.send_already_built_control_packet_for_top_k_path(dltPkt)
            # insertPkt = self.topKPathManager.insertPort(port, getRank(pathAndUtilist[i][1]))
            # controlPacketList.append(insertPkt)
            # portConfiguredIncurrentIteration[port] = port

            if(i==(len(pathAndUtilist))-1):
                insertPkt = self.topKPathManager.insertPort(port, getRank(pathAndUtilist[i][1]))
                controlPacketList.append(insertPkt)
            else:
                insertPkt = self.topKPathManager.insertPort(port, i)
                controlPacketList.append(insertPkt)

        # rankOrder = [4,6,8] # best 4 paths will be in rank 0, then 2 in next rank and so on
        # i=0
        # portConfiguredIncurrentIteration = {}
        # while i < len(pathAndUtilist):
        #     for r in range(0,len(rankOrder)):
        #         if i < rankOrder[r]:
        #             port = pathAndUtilist[i][0]
        #             if(portConfiguredIncurrentIteration.get(port)== None):
        #                 dltPkt = self.topKPathManager.deletePort(port)
        #                 self.p4dev.send_already_built_control_packet_for_top_k_path(dltPkt)
        #                 insertPkt = self.topKPathManager.insertPort(port, r)
        #                 self.p4dev.send_already_built_control_packet_for_top_k_path(insertPkt)
        #                 portConfiguredIncurrentIteration[port] = port
        #             else:
        #                 insertPkt = self.topKPathManager.insertPort(port, r)
        #                 self.p4dev.send_already_built_control_packet_for_top_k_path(insertPkt)
        #                 portConfiguredIncurrentIteration[port] = port
        #     i = i+1
        # for ctrlPkt in controlPacketList:
        #     self.p4dev.send_already_built_control_packet_for_top_k_path(ctrlPkt)



    def topKpathroutingTesting(self):
        time.sleep(25)
        i = 0
        while(True):
            j = i % len(tstConst.TOP_K_PATH_EXPERIMENT_PORT_RATE_CONFIGS)
            if(self.p4dev.devName != "device:p0l0"):
                return
            portCfg = tstConst.TOP_K_PATH_EXPERIMENT_PORT_RATE_CONFIGS[j]
            time.sleep(portCfg[0])
            for k in range(0,len(portCfg[1])): # k gives the rank iteslf as the port configs are already sorted
                if self.p4dev.fabric_device_config.switch_type == InternalConfig.SwitchType.LEAF:
                    port =portCfg[1][k][0]
                    portRank = portCfg[1][k][1]
                    portRate = portCfg[1][k][2]
                    bufferSize = portCfg[1][k][3]
                    setPortQueueRatesAndDepth(self.p4dev, port, portRate, bufferSize)
                if self.p4dev.fabric_device_config.switch_type == InternalConfig.SwitchType.SPINE:
                    port =portCfg[1][k][0]
                    portRank = portCfg[1][k][1]
                    portRate = portCfg[1][k][2]
                    bufferSize = portCfg[1][k][3]
                dltPkt = self.topKPathManager.deletePort(port)
                self.p4dev.send_already_built_control_packet_for_top_k_path(dltPkt)
                if(portRate> 0): # if 0 that means the port is not down . So need to iinsert it. but for rate < 0 we delete the port but do not insert it agian to simulate delete behavior
                    insertPkt = self.topKPathManager.insertPort(port, portRank)
                    self.p4dev.send_already_built_control_packet_for_top_k_path(insertPkt)
                else:
                    logger.info("Port : "+str(port)+" will not be configured into system as it's rate is <0 = ")
            print("Installed routes ",portCfg)
            topologyConfigFilePath =  ConfConst.TOPOLOGY_CONFIG_FILE
            # if(self.p4dev.devName == "device:p0l0"):
            #     testEvaluator = TestCommandDeployer(topologyConfigFilePath,
            #                                         "/home/deba/Desktop/Top-K-Path/testAndMeasurement/TestConfigs/TopKPathTesterWithTopKPath.json",
            #                                         ConfConst.IPERF3_CLIENT_PORT_START, ConfConst.IPERF3_SERVER_PORT_START, testStartDelay= 5)
            # testEvaluator.setupTestCase()
            i = i+ 1
Example #8
0
class TopKPathRouting:
    def __init__(self, dev):
        self.p4dev = dev
        self.testOperationIndex = 0
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            #self.topKPathManager = TopKPathManager(dev = self.p4dev, k=len(self.p4dev.portToSpineSwitchMap.keys()))
            self.topKPathManager = TopKPathManager(dev=self.p4dev,
                                                   k=ConfConst.K)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            # self.topKPathManager = TopKPathManager(dev = self.p4dev, k=len(self.p4dev.portToSuperSpineSwitchMap.keys()))
            self.topKPathManager = TopKPathManager(dev=self.p4dev,
                                                   k=ConfConst.K)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(
                dev=self.p4dev, k=ConfConst.K
            )  # by default add space for 16 ports in super spine. This is not actually used in our simulation
            pass

        return

    def initMAT(self, switchObject, bitMaskLength):
        allOneMAsk = BinaryMask(bitMaskLength)
        allOneMAsk.setAllBitOne()
        allOneMAskBinaryString = allOneMAsk.getBinaryString()
        for j in range(0, bitMaskLength):
            mask = BinaryMask(bitMaskLength)
            mask.setNthBitWithB(n=j, b=1)
            maskAsString = mask.getBinaryString()
            switchObject.addTernaryMatchEntry(
                "IngressPipeImpl.k_path_selector_control_block.kth_path_finder_mat",
                fieldName="local_metadata.kth_path_selector_bitmask",
                fieldValue=allOneMAskBinaryString,
                mask=maskAsString,
                actionName=
                "IngressPipeImpl.k_path_selector_control_block.kth_path_finder_action_with_param",
                actionParamName="rank",
                actionParamValue=str(j),
                priority=bitMaskLength - j + 1)

    def p4kpUtilBasedReconfigureForLeafSwitches(self, linkUtilStats,
                                                oldLinkUtilStats):
        # logger.info("CLB ALGORITHM: For switch "+ self.p4dev.devName+ "new Utilization data is  "+str(linkUtilStats))
        # logger.info("CLB ALGORITHM: For switch "+ self.p4dev.devName+ "old Utilization data is  "+str(oldLinkUtilStats))
        pathAndUtilist = []
        for i in range(int(ConfConst.MAX_PORTS_IN_SWITCH / 2),
                       ConfConst.MAX_PORTS_IN_SWITCH):
            if ((i + 1) in ConfigConst.reservedPortList) and (
                (ConfigConst.specialTunnelStartingSwitch in self.p4dev.devName)
                    or
                (ConfigConst.specialTunnelEndingSwitch in self.p4dev.devName)):
                continue
            else:
                index = i
                utilInLastInterval = linkUtilStats[index] - oldLinkUtilStats[
                    index]
                pathAndUtilist.append((i + 1, utilInLastInterval))
        pathAndUtilist.sort(key=lambda x: x[1])
        controlPacketList = []
        rankInsertedIncurrentIteration = {}
        i = 0
        extraIncrementToAvoidReserverRank = 0
        while i < len(pathAndUtilist):
            if (i in ConfigConst.reservedRanks) and (
                (ConfigConst.specialTunnelStartingSwitch in self.p4dev.devName)
                    or
                (ConfigConst.specialTunnelEndingSwitch in self.p4dev.devName)):
                extraIncrementToAvoidReserverRank = extraIncrementToAvoidReserverRank + 1
            port = pathAndUtilist[i][0]
            rank = i + extraIncrementToAvoidReserverRank
            if (rankInsertedIncurrentIteration.get(rank) == None):
                dltPkt = self.topKPathManager.deletePort(port)
                self.p4dev.send_already_built_control_packet_for_top_k_path(
                    dltPkt)
            rankInsertedIncurrentIteration[rank] = rank
            # print("INserting rank "+str(rank)+" and port "+str(port))
            insertPkt = self.topKPathManager.insertPort(port, rank)
            self.p4dev.send_already_built_control_packet_for_top_k_path(
                insertPkt)
            i = i + 1

    def processFeedbackPacket(self, parsedPkt, dev):
        #print("Called the algo")
        #TODO: for each of the different types of the packet, we have to write a separate function to process them
        pass

    def setup(self, nameToSwitchMap
              ):  #This one initially setup three path in same rank
        '''
        This function setup all the relevant stuffs for running the algorithm
        '''
        startingRankForTestingTopKPathProblem = 0
        self.initMAT(self.p4dev, ConfConst.K)
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            for k in self.p4dev.portToSpineSwitchMap.keys():
                if (k in ConfigConst.reservedPortList) and (
                    (ConfigConst.specialTunnelStartingSwitch
                     in self.p4dev.devName) or
                    (ConfigConst.specialTunnelEndingSwitch
                     in self.p4dev.devName)):
                    continue
                else:
                    pkt = self.topKPathManager.insertPort(
                        port=int(k), k=startingRankForTestingTopKPathProblem)
                    self.p4dev.send_already_built_control_packet_for_top_k_path(
                        pkt)
            i = 0
            while i < len(ConfigConst.reservedPortList):
                pkt = self.topKPathManager.insertPort(
                    port=int(ConfigConst.reservedPortList[i]),
                    k=ConfigConst.reservedRanks[i])
                self.p4dev.send_already_built_control_packet_for_top_k_path(
                    pkt)
                i = i + 1
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE:
            for k in self.p4dev.portToSuperSpineSwitchMap.keys():
                if (k in ConfigConst.reservedPortList):
                    continue
                else:
                    pkt = self.topKPathManager.insertPort(
                        port=int(k), k=startingRankForTestingTopKPathProblem)
                    self.p4dev.send_already_built_control_packet_for_top_k_path(
                        pkt)
        elif self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SUPER_SPINE:
            self.topKPathManager = TopKPathManager(
                dev=self.p4dev, k=ConfConst.K
            )  # by default add space for 16 ports in super spine. This is not actually used in our simulation
            pass
        if self.p4dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF:
            self.link_reconfiguration_thread = threading.Thread(
                target=self.linkReconfigurator, args=())
            self.link_reconfiguration_thread.start()
            logger.info("TopKpathrouting link_reconfiguration_thread  started")
        #else we do not need this process for spine switches because we are simulatin only layer 2 fat tree
        return

    def linkReconfigurator(self):
        time.sleep(25)
        i = 0
        # if(self.p4dev.devName != "device:p0l0"):
        #     return
        while (True):
            j = i % len(tstConst.MULTI_TENANCY_PORT_RATE_CONFIGS)
            portRates = tstConst.MULTI_TENANCY_PORT_RATE_CONFIGS[j]
            logger.info("PortRates are : " + str(portRates))
            rankInsertedIncurrentIteration = {}
            for k in range(0, len(portRates)):
                print(portRates[k])
                port = portRates[k][0]
                rate = int(
                    math.floor(
                        portRates[k][1] *
                        ConfConst.queueRateForSpineFacingPortsOfLeafSwitch))
                bufferSize = int(
                    math.floor(ConfigConst.QUEUE_RATE_TO_QUEUE_DEPTH_FACTOR *
                               rate))
                if (bufferSize < 200):
                    bufferSize = 200
                rank = getRankFromPPSRate(rate)
                # logger.info("Port "+str(port)+ " rate :"+str(portRates[k][1])+" rank:"+str(rank))
                setPortQueueRatesAndDepth(
                    dev=self.p4dev,
                    port=port,
                    queueRate=rate,
                    bufferSize=ConfigConst.QUEUE_RATE_TO_QUEUE_DEPTH_FACTOR)
                # if(rankInsertedIncurrentIteration.get(rank)== None):
                #     dltPkt = self.topKPathManager.deletePort(port)
                #     self.p4dev.send_already_built_control_packet_for_top_k_path(dltPkt)
                dltPkt = self.topKPathManager.deletePort(port)
                if (dltPkt != None):
                    self.p4dev.send_already_built_control_packet_for_top_k_path(
                        dltPkt)
                rankInsertedIncurrentIteration[rank] = rank
                # print("INserting rank "+str(rank)+" and port "+str(port))
                insertPkt = self.topKPathManager.insertPort(port, rank)
                self.p4dev.send_already_built_control_packet_for_top_k_path(
                    insertPkt)
            time.sleep(ConfigConst.MULTITENANCY_RATE_RECONFIGURATION_INTERVAL)
            i = i + 1