Ejemplo n.º 1
0
def setupFlowtypeBasedIngressRateMonitoringForKPathProblem(dev):
    upwardPortList = []
    if (dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF):
        upwardPortList = list(dev.portToSpineSwitchMap.keys())
        p = upwardPortList[
            0]  # for testing the K-path system just taking the total incoming capacity of a leaf-to-host port
        totalRate = 0
        if dev.portToQueueRateMap[str(p)] != None:
            totalRate = totalRate + int(dev.portToQueueRateMap[str(p)])

        for i in range(0, len(ConfConst.TRAFFIC_CLASS_AS_LIST)):
            tClass = ConfConst.TRAFFIC_CLASS_AS_LIST[i]
            #(tableName, fieldName, fieldValue, actionName, actionParamName, actionParamValue):)
            dev.addExactMatchEntry(
                tableName="flow_type_based_ingress_stats_table",
                fieldName="hdr.ipv6.traffic_class",
                fieldValue=str(tClass),
                actionName="monitor_incoming_flow_based_on_flow_type",
                actionParamName="flow_type_based_meter_idx",
                actionParamValue=str(tClass))
            me = sh.MeterEntry(
                dev,
                "IngressPipeImpl.ingress_rate_monitor_control_block.flow_type_based_ingress_meter_for_upstream"
            )
            me.index = tClass
            cir = int(
                (totalRate *
                 ConfConst.UPWARD_PORT_METER_CONFIG_FOR_TOP_K_PATH[0]) / 100)
            cburst = int(
                (totalRate * ConfConst.UPWARD_PORT_BURST_RATE_FORTOP_K_PATH) /
                100)
            pir = int(
                (totalRate *
                 ConfConst.UPWARD_PORT_METER_CONFIG_FOR_TOP_K_PATH[1]) / 100)
            pburst = int(
                (totalRate * ConfConst.UPWARD_PORT_BURST_RATE_FORTOP_K_PATH) /
                100)
            me.cir = cir
            me.cburst = cburst
            me.pir = cir + pir
            me.pburst = pburst
            me.modify()

    elif ((dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE)
          or (dev.fabric_device_config.switch_type
              == intCoonfig.SwitchType.SUPER_SPINE)):
        # For testingv with layer-2 fat-tree topology we do not need think about  spine or super spine switch
        pass

    pass
Ejemplo n.º 2
0
    def test_meter_entry(self):
        ce = sh.MeterEntry("MeterA")
        ce.index = 99
        ce.cir = 1
        ce.cburst = 2
        ce.pir = 3
        ce.pburst = 4
        expected_entry = """
meter_id: 335597387
index {
  index: 99
}
config {
  cir: 1
  cburst: 2
  pir: 3
  pburst: 4
}
"""
        expected_req = self.make_write_request(p4runtime_pb2.Update.MODIFY,
                                               P4RuntimeEntity.meter_entry,
                                               expected_entry)
        ce.modify()
        self.servicer.Write.assert_called_with(ProtoCmp(expected_req), ANY)

        self.simple_read_check(expected_req.updates[0].entity, ce,
                               P4RuntimeEntity.meter_entry)

        ce.index = None
        expected_entry = """
meter_id: 335597387
config {
  cir: 1
  cburst: 2
  pir: 3
  pburst: 4
}
"""
        expected_req = self.make_write_request(p4runtime_pb2.Update.MODIFY,
                                               P4RuntimeEntity.meter_entry,
                                               expected_entry)
        ce.modify()
        self.servicer.Write.assert_called_with(ProtoCmp(expected_req), ANY)
Ejemplo n.º 3
0
def setupFlowtypeBasedIngressRateMonitoring(dev):
    '''
    We have setup the port queue rates earlier and ther are stored in portToQueueRateMap. But the problem in they are setup for single port.
    In case of if we have multiple queue per port, we may have to setup the rates separately for each of the queue of each of the ports. Same is true for queue depths also.
    Currently bmv2 sets the rate for each queue in same quantity/ but if we do not use the scheduler programmability then it doesn't directly impacts the rate. because
    By default all packets are passed through queue 0. so a specific rate is applied to that queue. and the ultimate rate given by the swithc is that rate. but if our machine supports, and
    we can use the schedulers correctly, we should get 8* rate number pf packets per second. Now the question arrises, about the ingress port rates. Here most probably bmv2 do not applies any rate
    . So we have to use our own meter here and set the rate according to our environment.

    For ingress ports, bmv2 keeps 1K buffer, but there is no specific queue rate mechanism here. so we have to keep the rate record our own self. also same logic applicable for queue depth.
    After completion we have to start a all-to-all test. from that we have to decide about what is the average rate all ports can sustain. That will be the queue rate for all ports.
    :param dev:
    :return:
    '''

    #sum total processing rate of all the host facing ports. among the total rate keep a percent reserve for one kinf of flow. rest for other kind of flow.
    # if switch is leaf type -- find sum of total packet processing rates for host facing ports
    # else if switch is spine type  -- find sum of total packet processing rates for leaf facing ports
    # if switch is super spine type  -- find sum of total packet processing rates for spine facing ports
    downwardPortList = []
    upwardPortList = []
    if (dev.fabric_device_config.switch_type == intCoonfig.SwitchType.LEAF):
        totalRateOfDownWardPorts = getTotalPacketProcessingRatesForPortList(
            dev, list(dev.portToHostMap.keys()))
        downwardPortList = list(dev.portToHostMap.keys())
        totalRateOfUpwordPorts = getTotalPacketProcessingRatesForPortList(
            dev, list(dev.portToSpineSwitchMap.keys()))
        upwardPortList = list(dev.portToSpineSwitchMap.keys())
    elif (dev.fabric_device_config.switch_type == intCoonfig.SwitchType.SPINE):
        totalRateOfDownWardPorts = getTotalPacketProcessingRatesForPortList(
            dev, list(dev.portToLeafSwitchMap.keys()))
        downwardPortList = list(dev.portToLeafSwitchMap.keys())
        upwardPortList = list(dev.portToSuperSpineSwitchMap.keys())
        totalRateOfUpwordPorts = getTotalPacketProcessingRatesForPortList(
            dev, list(dev.portToSuperSpineSwitchMap.keys()))
    elif (dev.fabric_device_config.switch_type ==
          intCoonfig.SwitchType.SUPER_SPINE):
        totalRateOfDownWardPorts = getTotalPacketProcessingRatesForPortList(
            dev, list(dev.portToSpineSwitchMap.keys()))
        downwardPortList = list(dev.portToSpineSwitchMap.keys())
        upwardPortList = [
        ]  #For super spine we are not working for connectivity toward internet
        totalRateOfUpwordPorts = getTotalPacketProcessingRatesForPortList(
            dev, list(dev.portToSpineSwitchMap.keys()))

        #port x traffic_class --> action (traffic_class) --> rate of meter[traffic_class] = rate_array[traffic_class_index]
    for p in downwardPortList:
        for i in range(0, len(ConfConst.TRAFFIC_CLASS_AS_LIST)):
            tClass = ConfConst.TRAFFIC_CLASS_AS_LIST[i]
            dev.addExactMatchEntryWithMultipleField(
                tableName=
                "IngressPipeImpl.ingress_rate_monitor_control_block.flow_type_based_ingress_stats_table",
                fieldNameList=[
                    "standard_metadata.ingress_port", "hdr.ipv6.traffic_class"
                ],
                fieldValueList=[p, tClass],
                actionName=
                "IngressPipeImpl.ingress_rate_monitor_control_block.monitor_incoming_flow_based_on_flow_type_for_pkts_rcvd_from_downstream",
                actionParamName="flow_type_based_meter_idx",
                actionParamValue=str(tClass))
            me = sh.MeterEntry(
                dev,
                "IngressPipeImpl.ingress_rate_monitor_control_block.flow_type_based_ingress_meter_for_downstream"
            )
            me.index = tClass
            me.cir = int(
                (totalRateOfDownWardPorts * ConfConst.
                 PERCENTAGE_OF_TOTAL_UPWARD_TRAFFIC_FOR_TRAFFIC_CLASS[i]) /
                100)
            me.cburst = int(
                math.ceil((totalRateOfDownWardPorts - int(
                    (totalRateOfDownWardPorts * ConfConst.
                     PERCENTAGE_OF_TOTAL_UPWARD_TRAFFIC_FOR_TRAFFIC_CLASS[i]))
                           / 100) / 5))  # 1/5 th of the rest of the bandwidth
            me.pir = int(totalRateOfDownWardPorts *
                         0.95)  # 95 %of the total traffic
            me.pburst = int(math.ceil((totalRateOfDownWardPorts * 0.05)))
            me.modify()
    for p in upwardPortList:
        for i in range(0, len(ConfConst.TRAFFIC_CLASS_AS_LIST)):

            tClass = ConfConst.TRAFFIC_CLASS_AS_LIST[i]
            dev.addExactMatchEntryWithMultipleField(
                tableName=
                "IngressPipeImpl.ingress_rate_monitor_control_block.flow_type_based_ingress_stats_table",
                fieldNameList=[
                    "standard_metadata.ingress_port", "hdr.ipv6.traffic_class"
                ],
                fieldValueList=[p, tClass],
                actionName=
                "IngressPipeImpl.ingress_rate_monitor_control_block.monitor_incoming_flow_based_on_flow_type_for_pkts_rcvd_from_upstream",
                actionParamName="flow_type_based_meter_idx",
                actionParamValue=str(tClass))
            me = sh.MeterEntry(
                dev,
                "IngressPipeImpl.ingress_rate_monitor_control_block.flow_type_based_ingress_meter_for_upstream"
            )
            me.index = tClass
            me.cir = int(
                (totalRateOfDownWardPorts * ConfConst.
                 PERCENTAGE_OF_TOTAL_UPWARD_TRAFFIC_FOR_TRAFFIC_CLASS[i]) /
                100)
            me.cburst = int(
                math.ceil((totalRateOfDownWardPorts - int(
                    (totalRateOfDownWardPorts * ConfConst.
                     PERCENTAGE_OF_TOTAL_UPWARD_TRAFFIC_FOR_TRAFFIC_CLASS[i]))
                           / 100) / 5))  # 1/5 th of the rest of the bandwidth
            me.pir = int(totalRateOfDownWardPorts *
                         0.95)  # 95 %of the total traffic
            me.pburst = int(math.ceil((totalRateOfDownWardPorts * 0.05)))
            me.modify()