示例#1
0
 def tcp_udp_flows(self, vlan_id, nfvip, eth_type, nat_flows):
     return (
         # Learn from coprocessor port/do inbound translation.
         (self.FROM_COPRO_TABLE,
          parser.OFPMatch(eth_type=eth_type,
                          vlan_vid=vlan_id), nat_flows(nfvip)),
         # Packets from coprocessor go to tuple inbound table.
         (self.INTF_TABLE,
          parser.OFPMatch(eth_type=eth_type,
                          ip_proto=socket.IPPROTO_TCP,
                          in_port=COPROPORT,
                          vlan_vid=vlan_id),
          [parser.OFPInstructionGotoTable(self.FROM_COPRO_TABLE)]),
         (self.INTF_TABLE,
          parser.OFPMatch(eth_type=eth_type,
                          ip_proto=socket.IPPROTO_UDP,
                          in_port=COPROPORT,
                          vlan_vid=vlan_id),
          [parser.OFPInstructionGotoTable(self.FROM_COPRO_TABLE)]),
         # Packets from fake interface go outbound table.
         (self.INTF_TABLE,
          parser.OFPMatch(eth_type=eth_type,
                          ip_proto=socket.IPPROTO_TCP,
                          in_port=FAKEPORT,
                          vlan_vid=vlan_id),
          [parser.OFPInstructionGotoTable(self.TO_COPRO_TABLE)]),
         (self.INTF_TABLE,
          parser.OFPMatch(eth_type=eth_type,
                          ip_proto=socket.IPPROTO_UDP,
                          in_port=FAKEPORT,
                          vlan_vid=vlan_id),
          [parser.OFPInstructionGotoTable(self.TO_COPRO_TABLE)]))
示例#2
0
    def add_routes(self, datapath, local_port, mac):
        """ Add the routes to all switches when a new mac is learned """
        # Add the route to the switch the device is connected to
        local_route = parser.OFPFlowMod(
            datapath=datapath,
            table_id=0,
            priority=20,
            cookie=3,
            command=ofproto.OFPFC_ADD,
            match=parser.OFPMatch(eth_dst=mac),
            instructions=[
                parser.OFPInstructionGotoTable(1),
                parser.OFPInstructionActions(
                    type_=ofproto.OFPIT_WRITE_ACTIONS,
                    actions=[parser.OFPActionOutput(local_port)])
            ])
        datapath.send_msg(local_route)

        # Now add routes to all other switches that can get there
        bfs = self.breadth_first_search(datapath.id)
        for dpid, port in bfs.iteritems():
            dp = self.switches[dpid]
            foreign_route = parser.OFPFlowMod(
                datapath=dp,
                table_id=0,
                priority=10,
                cookie=3,
                command=ofproto.OFPFC_ADD,
                match=parser.OFPMatch(eth_dst=mac),
                instructions=[
                    parser.OFPInstructionGotoTable(1),
                    parser.OFPInstructionActions(
                        type_=ofproto.OFPIT_WRITE_ACTIONS,
                        actions=[parser.OFPActionOutput(port)])
                ])
            dp.send_msg(foreign_route)

        # Add the route to table 1 so we don't get messages about
        # this mac address anymore
        for dp in self.switches.values():
            block_route = parser.OFPFlowMod(datapath=dp,
                                            table_id=1,
                                            priority=20,
                                            cookie=3,
                                            command=ofproto.OFPFC_ADD,
                                            match=parser.OFPMatch(eth_src=mac),
                                            instructions=[])
            dp.send_msg(block_route)
示例#3
0
    def test_flow_stats(self):
        """Check the update method in the GaugeFlowStatsLogger class"""

        # add an ofproto attribute to the datapath
        datapath = create_mock_datapath(0)
        ofp_attr = {'ofproto': ofproto}
        datapath.configure_mock(**ofp_attr)

        # add the datapath as an attribute to the config
        dp_attr = {'dp': datapath}
        self.conf.configure_mock(**dp_attr)

        logger = watcher.GaugeFlowTableLogger(self.conf, '__name__',
                                              mock.Mock())
        logger._running = True
        instructions = [parser.OFPInstructionGotoTable(1)]

        msg = flow_stats_msg(datapath, instructions)
        rcv_time = time.time()
        rcv_time_str = logger._rcv_time(rcv_time)
        logger.update(rcv_time, msg)
        log_str = self.get_file_contents("{}--flowtable--{}.json".format(
            datapath.name, rcv_time_str))

        yaml_dict = yaml.safe_load(
            log_str)['OFPFlowStatsReply']['body'][0]['OFPFlowStats']

        compare_flow_msg(msg, yaml_dict, self)
示例#4
0
    def test_flow_stats(self):
        """Check the update method in the GaugeFlowStatsLogger class"""

        #add an ofproto attribute to the datapath
        datapath = create_mock_datapath(0)
        ofp_attr = {'ofproto': ofproto}
        datapath.configure_mock(**ofp_attr)

        #add the datapath as an attribute to the config
        dp_attr = {'dp' : datapath}
        self.conf.configure_mock(**dp_attr)

        logger = watcher.GaugeFlowTableLogger(self.conf, '__name__', mock.Mock())
        instructions = [parser.OFPInstructionGotoTable(1)]

        msg = flow_stats_msg(datapath, instructions)
        logger.update(time.time(), datapath.dp_id, msg)
        log_str = self.get_file_contents()

        #only parse the message part of the log text
        str_to_find = "msg: "
        index = log_str.find(str_to_find)
        #discard the start of the log text
        log_str = log_str[index + len(str_to_find):]
        json_dict = json.loads(log_str)['OFPFlowStatsReply']['body'][0]['OFPFlowStats']

        compare_flow_msg(msg, json_dict, self)
示例#5
0
 def ipv4_flows(self, vlan_id, nfvip):
     return (
         # Program OVS to respond to ARP on fake port.
         (self.TO_COPRO_TABLE, parser.OFPMatch(eth_type=ether.ETH_TYPE_ARP, vlan_vid=vlan_id),
          self.arp_reply_actions()),
         (self.INTF_TABLE, parser.OFPMatch(
             eth_type=ether.ETH_TYPE_ARP, eth_src=self.FAKESERVERMAC, in_port=self.FAKEPORT, arp_op=arp.ARP_REQUEST, vlan_vid=vlan_id),
          [parser.OFPInstructionGotoTable(self.TO_COPRO_TABLE)])) + self.tcp_udp_flows(vlan_id, nfvip, ether.ETH_TYPE_IP, self.natv4_flows)
示例#6
0
def goto_table_id(table_id):
    """Return instruction to goto table by table ID.

    Args:
        table (int): table by ID to goto.
    Returns:
        ryu.ofproto.ofproto_v1_3_parser.OFPInstruction: goto instruction.
    """
    return parser.OFPInstructionGotoTable(table_id)
示例#7
0
def goto_table(table):
    """Return instruction to goto table.

    Args:
        table (ValveTable): table to goto.
    Returns:
        ryu.ofproto.ofproto_v1_3_parser.OFPInstruction: goto instruction.
    """
    return parser.OFPInstructionGotoTable(table.table_id)
示例#8
0
def metadata_goto_table(metadata, mask, table):
    """Return instructions to write metadata and goto table.

    Args:
        metadata (int): metadata to write to packet
        maks (int): mask to apply to metadata
        table (ValveTable): table to goto.
    Returns:
        list of OFPInstructions"""
    return [
        parser.OFPInstructionWriteMetadata(metadata, mask),
        parser.OFPInstructionGotoTable(table.table_id)
        ]
 def add_tcp_table(self, datapath):
     ofproto = datapath.ofproto
     parser = datapath.ofproto_parser
     inst = [parser.OFPInstructionGotoTable(1)]
     match = parser.OFPMatch()
     mod = parser.OFPFlowMod(datapath=datapath,
                             table_id=0,
                             priority=0,
                             match=match,
                             idle_timeout=0,
                             hard_timeout=0,
                             instructions=inst)
     datapath.send_msg(mod)
     self.Flowcounter[datapath.id] += 1
示例#10
0
    def test_flow_stats(self):
        """Check the update method of the GaugeFlowTableInfluxDBLogger class"""

        conf = self.create_config_obj(create_mock_datapath(0))
        db_logger = gauge_influx.GaugeFlowTableInfluxDBLogger(
            conf, '__name__', mock.Mock())
        db_logger._running = True

        rcv_time = int(time.time())
        instructions = [parser.OFPInstructionGotoTable(1)]
        msg = flow_stats_msg(conf.dp, instructions)
        db_logger.update(rcv_time, msg)

        other_fields = {
            'dp_name': conf.dp.name,
            'dp_id': hex(conf.dp.dp_id),
            'timestamp': rcv_time,
            'priority': msg.body[0].priority,
            'table_id': msg.body[0].table_id,
            'inst_count': len(msg.body[0].instructions),
            'vlan': msg.body[0].match.get('vlan_vid') ^ ofproto.OFPVID_PRESENT,
            'cookie': msg.body[0].cookie,
        }

        with open(self.server.output_file, 'r') as log:
            output = log.readlines()

        for line in output:
            measurement, influx_data = self.parse_influx_output(line)

            for stat_name, stat_val in influx_data.items():
                if stat_name == 'value':
                    if measurement == 'flow_packet_count':
                        self.assertEqual(msg.body[0].packet_count, stat_val)
                    elif measurement == 'flow_byte_count':
                        self.assertEqual(msg.body[0].byte_count, stat_val)
                    else:
                        self.fail("Unknown measurement")

                elif stat_name in other_fields:
                    self.assertEqual(other_fields[stat_name], stat_val)

                elif stat_name in msg.body[0].match:
                    self.assertEqual(msg.body[0].match.get(stat_name),
                                     stat_val)

                else:
                    self.fail("Unknown key: {} and value: {}".format(
                        stat_name, stat_val))
示例#11
0
    def test_flow_stats(self):
        """Check the update method of the GaugeFlowTableInfluxDBLogger class"""

        conf = self.create_config_obj(create_mock_datapath(0))
        db_logger = gauge_influx.GaugeFlowTableInfluxDBLogger(
            conf, '__name__', mock.Mock())

        rcv_time = int(time.time())
        matches = self.generate_all_matches()
        instructions = [parser.OFPInstructionGotoTable(1)]
        flow_stats = [
            parser.OFPFlowStats(0, 0, 0, 1, 0, 0, 0, 0, 1, 1, matches,
                                instructions)
        ]
        message = parser.OFPFlowStatsReply(conf.dp, body=flow_stats)
        db_logger.update(rcv_time, conf.dp.id, message)

        other_fields = {
            'dp_name': conf.dp.name,
            'timestamp': rcv_time,
            'priority': flow_stats[0].priority,
            'table_id': flow_stats[0].table_id,
            'inst_count': len(flow_stats[0].instructions),
            'vlan': matches.get('vlan_vid') ^ ofproto.OFPVID_PRESENT
        }

        self.server.output_file.seek(0)
        for line in self.server.output_file.readlines():
            measurement, influx_data = self.parse_influx_output(line)

            for stat_name, stat_val in influx_data.items():
                if stat_name == 'value':
                    if measurement == 'flow_packet_count':
                        self.assertEqual(flow_stats[0].packet_count, stat_val)
                    elif measurement == 'flow_byte_count':
                        self.assertEqual(flow_stats[0].byte_count, stat_val)
                    else:
                        self.fail("Unknown measurement")

                elif stat_name in other_fields:
                    self.assertEqual(other_fields[stat_name], stat_val)

                elif stat_name in matches:
                    self.assertEqual(matches.get(stat_name), stat_val)

                else:
                    self.fail("Unknown key: {} and value: {}".format(
                        stat_name, stat_val))
示例#12
0
    def test_flow_stats(self):
        """Check the update method of the GaugeFlowTablePrometheusPoller class"""

        datapath = create_mock_datapath(2)

        conf = mock.Mock(dp=datapath,
                         type='',
                         interval=1,
                         prometheus_port=9303,
                         prometheus_addr='localhost',
                         use_test_thread=True)

        prom_poller = gauge_prom.GaugeFlowTablePrometheusPoller(
            conf, '__name__', self.prom_client)
        rcv_time = int(time.time())
        instructions = [parser.OFPInstructionGotoTable(1)]
        msg = flow_stats_msg(conf.dp, instructions)
        prom_poller.update(rcv_time, conf.dp.dp_id, msg)
示例#13
0
    def test_update(self):
        """Compares the data writtten to the CouchDB server and the original flow message"""
        db_logger = gauge_nsodbc.GaugeFlowTableDBLogger(self.conf, '__name__', mock.Mock())
        rcv_time = int(time.time())
        instructions = [parser.OFPInstructionGotoTable(1)]
        msg = flow_stats_msg(self.conf.dp, instructions)
        db_logger.update(rcv_time, self.conf.dp.dp_id, msg)

        for doc in self.server.docs:
            if doc.startswith(self.conf.flows_doc) and '_design' not in doc:
                flow_doc = self.server.docs[doc]
            elif doc.startswith(self.conf.switches_doc) and '_design' not in doc:
                switch_doc = self.server.docs[doc]

        self.assertEqual(switch_doc['data']['flows'][0], flow_doc['_id'])
        flow_doc = flow_doc['data']['OFPFlowStats']

        compare_flow_msg(msg, flow_doc, self)
示例#14
0
    def _send_flow_mod(self, obj):
        inst_type = False
        table_id = 0
        flow_mod = obj.get("OFPFlowMod")
        datapath = self.dpstore.get(flow_mod.get("datapath_id"))
        datapath = datapath.get("dp_obj")
        instructions = flow_mod.get("instructions")

        # FIXME: put this in a instruction parser
        for instruction in instructions:
            if "OFPInstructionActions" in instruction:
                inst_type = "OFPInstructionActions"
                actions = self._parse_action(
                    instruction.get("OFPInstructionActions").get("actions"))
            if "OFPInstructionGotoTable" in instruction:
                inst_type = "OFPInstructionGotoTable"
                table_id = instruction.get("OFPInstructionGotoTable").get(
                    "table_id")
                goto = ofproto_v1_3_parser.OFPInstructionGotoTable(table_id)

        match = flow_mod.get("match")
        match = self._pars_match(match)

        if inst_type == "OFPInstructionActions":
            inst = [
                ofproto_v1_3_parser.OFPInstructionActions(
                    ofproto_v1_3.OFPIT_APPLY_ACTIONS, actions)
            ]
        if inst_type == "OFPInstructionGotoTable":
            inst = [goto]
        if int(flow_mod.get("table_id")) >= 0:
            table_id = int(flow_mod.get("table_id"))

        mod = ofproto_v1_3_parser.OFPFlowMod(datapath=datapath,
                                             priority=int(
                                                 flow_mod.get("priority")),
                                             match=match,
                                             instructions=inst,
                                             table_id=table_id)

        datapath.send_msg(mod)
示例#15
0
    def test_flow_stats(self):
        """Check the update method in the GaugeFlowStatsLogger class"""

        #add an ofproto attribute to the datapath
        datapath = create_mock_datapath(0)
        ofp_attr = {'ofproto': ofproto}
        datapath.configure_mock(**ofp_attr)

        #add the datapath as an attribute to the config
        dp_attr = {'dp' : datapath}
        self.conf.configure_mock(**dp_attr)

        logger = watcher.GaugeFlowTableLogger(self.conf, '__name__', mock.Mock())
        instructions = [parser.OFPInstructionGotoTable(1)]

        msg = flow_stats_msg(datapath, instructions)
        logger.update(time.time(), datapath.dp_id, msg)
        log_str = self.get_file_contents()

        yaml_dict = yaml.load(log_str)['msg']['OFPFlowStatsReply']['body'][0]['OFPFlowStats']

        compare_flow_msg(msg, yaml_dict, self)
示例#16
0
def instructions_to_ryu(instructions, rule):
    """ Converts Instructions to a list of ryu instructions

        This returns both a instruction list and any extra messages that
        are required to install the instructions such as group mod messages.
        Currently this is not smart about reusing groups.

        instructions: A Instructions object
        rule: A Rule
        return: A tuple ([instructions], [extra messages])
    """
    ret = []
    extra_messages = []
    if instructions.goto_table is not None:
        ret.append(parser.OFPInstructionGotoTable(instructions.goto_table))
    if instructions.write_metadata is not None:
        assert not "TODO"
    if (instructions.write_actions is not None
            and not instructions.write_actions.empty()):
        actions, extra = actions_to_ryu(instructions.write_actions, rule)
        ret.append(
            parser.OFPInstructionActions(ofproto_v1_3.OFPIT_WRITE_ACTIONS,
                                         actions))
        extra_messages += extra
    if (instructions.apply_actions is not None
            and not instructions.apply_actions.empty()):
        actions, extra = actions_to_ryu(instructions.apply_actions, rule)
        ret.append(
            parser.OFPInstructionActions(ofproto_v1_3.OFPIT_APPLY_ACTIONS,
                                         actions))
        extra_messages += extra
    if instructions.clear_actions is True:
        ret.append(
            parser.OFPInstructionActions(ofproto_v1_3.OFPIT_CLEAR_ACTIONS))
    if instructions.meter is not None:
        assert not "TODO"

    return (ret, extra_messages)
示例#17
0
    def install_transport_bad(self, datapath):
        """ Set table 0 as stateful solo per usare GD, fa le somme del percorso """
        req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                       table_id=0,
                                                       stateful=1)
        datapath.send_msg(req)
        """ Ci sta una table NULLA per i bug di OpenFLow con le Label MPLS """
        """ Set table 2 as stateful, verifica le condizioni sul percorso <="""
        req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                       table_id=2,
                                                       stateful=1)
        datapath.send_msg(req)
        """ Set table 3 as stateful """
        req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                       table_id=3,
                                                       stateful=1)
        datapath.send_msg(req)

        ############################### LOOKUP/UPDATE ################
        """ Tab0 """
        """ Non mi interessa """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=0)
        datapath.send_msg(req)
        """ Non mi interessa  """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=0)
        datapath.send_msg(req)
        """ Tab2 """
        """ Set lookup extractor = {MAC_SRC} """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=2)
        datapath.send_msg(req)
        """ Set update extractor = {MAC_SRC}  """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=2)
        datapath.send_msg(req)
        """ Tab3 """
        """ Set lookup extractor = {MAC_DST} """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_DST],
            table_id=3)
        datapath.send_msg(req)
        """ Set update extractor = {MAC_SRC}  """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=3)
        datapath.send_msg(req)

        ########################### SET HF GD DATA VARIABLE TAB 0 ############################################
        ''' HF[1] = OXM_OF_MPLS_TC [pesoArchi] '''
        req = osparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=0,
            extractor_id=1,
            field=ofproto.OXM_OF_MPLS_TC)
        datapath.send_msg(req)
        ''' GD[0] = 0 '''
        req = osparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=0, global_data_variable_id=0, value=0)
        datapath.send_msg(req)

        ########################### SET HF GD DATA VARIABLE TAB 2 ############################################
        ''' HF[1] = OXM_OF_MPLS_TC [pesoArchi] '''
        req = osparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=2,
            extractor_id=1,
            field=ofproto.OXM_OF_MPLS_TC)
        datapath.send_msg(req)

        ########################### SET CONDITION TAB 2 ############################################

        # condition 3: MPLS_TC <= COSTO MEMORIZZATO (FD[0]) ?
        # condition 3: HF[1] <= FD[0] ?
        req = osparser.OFPExpMsgSetCondition(datapath=datapath,
                                             table_id=2,
                                             condition_id=0,
                                             condition=osproto.CONDITION_LTE,
                                             operand_1_hf_id=1,
                                             operand_2_fd_id=0)
        datapath.send_msg(req)
        '''####################### TAB 0 '''
        ''' somma il costo del link di ingresso al valore memorizzato nel pacchetto mpls_tc + 1 '''
        """ Riga 1 """

        # GD[0] = HF[1] + 1 -> MPLS_TC + 1
        # HF [1] = GD[0] -> MPLS_TC = GD[0]
        # GOTO Tab 2
        match = ofparser.OFPMatch(eth_type=0x8847)
        actions = [
            osparser.OFPExpActionSetDataVariable(table_id=0,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_gd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=2),
            osparser.OFPExpActionWriteContextToField(
                src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_MPLS_TC)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(1)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=1198,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 1 NULLA  serve solo per i bug di OpenFlow, servono 2 stage xke le modifiche MPLS siano visibili'''
        # Non fa niente, ci sta solo per risolvere bug (presunti) di OpenFlow
        match = ofparser.OFPMatch(eth_type=0x8847)
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(2)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=0,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        '''# #######################  TAB 2 '''
        ''' C[0] verifica se il costo memorizzato nel pacchetto e' <= di quello gia conosciuto (in pratica se il pacchetto ha fatto un percorso migliore) '''
        """ Riga 1 """

        # C[0]: MPLS_TC > COSTO MEMORIZZATO -> HF[1] > FD[0]
        # MetaData: 1 -> Pacchetto duplicato
        # azione DROP
        match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=0)
        actions = [osparser.OFPExpActionSetState(state=1, table_id=2)]
        self.add_flow(datapath=datapath,
                      table_id=2,
                      priority=198,
                      match=match,
                      actions=actions)
        """ Riga 2 """

        # C[0]: MPLS_TC <= COSTO MEMORIZZATO -> HF[1] <= FD[0]
        # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC
        # SetState(1)
        # azione GOTO Tab 3
        match = ofparser.OFPMatch(state=1, eth_type=0x8847, condition0=1)
        actions = [
            osparser.OFPExpActionSetState(state=1, table_id=2),
            osparser.OFPExpActionSetDataVariable(table_id=2,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_fd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=0)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(3)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=2,
                                  priority=98,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        """ Riga 3 """

        # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC
        # SetState(1)
        # azione GOTO Tab 3
        match = ofparser.OFPMatch(state=0, eth_type=0x8847)
        actions = [
            osparser.OFPExpActionSetState(state=1, table_id=2),
            osparser.OFPExpActionSetDataVariable(table_id=2,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_fd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=0)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(3)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=2,
                                  priority=8,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        '''# #######################  TAB 3  semplicemente MAC Learning '''

        # for each input port, for each state
        for i in range(1, N + 1):
            for s in range(N + 1):
                match = ofparser.OFPMatch(in_port=i, state=s)
                if s == 0:
                    out_port = ofproto.OFPP_FLOOD
                else:
                    out_port = s
                # actions = [osparser.OFPExpActionSetState(state=i, table_id=3, hard_timeout=10),
                actions = [
                    osparser.OFPExpActionSetState(state=i, table_id=3),
                    ofparser.OFPActionOutput(out_port)
                ]
                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=0,
                              match=match,
                              actions=actions)
示例#18
0
	def switch_features_handler(self, event):

		""" Switche sent his features, check if OpenState supported """
		msg = event.msg
		datapath = msg.datapath

		LOG.info("Configuring switch %d..." % datapath.id)

		""" Set table 0 as stateful """
		req = bebaparser.OFPExpMsgConfigureStatefulTable(
				datapath=datapath,
				table_id=0,
				stateful=1)
		datapath.send_msg(req)

		""" Set table 1 as stateful """
		req = bebaparser.OFPExpMsgConfigureStatefulTable(
				datapath=datapath,
				table_id=1,
				stateful=1)
		datapath.send_msg(req)


	############################### LOOKUP/UPDATE ################

		""" Set lookup extractor = {eth_dst} """
		req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath,
				command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
				fields=[ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST],
				table_id=0,
				biflow=1)
		datapath.send_msg(req)

		""" Set update extractor = {eth_src}  """
		req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath,
				command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
				fields=[ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST],
				table_id=0,
				biflow=1)
		datapath.send_msg(req)


		""" Set lookup extractor = {eth_dst} """
		req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath,
				command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
				fields=[ofproto.OXM_OF_ETH_SRC],
				table_id=1)
		datapath.send_msg(req)

		""" Set update extractor = {eth_src}  """
		req = bebaparser.OFPExpMsgKeyExtract(datapath=datapath,
				command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
				fields=[ofproto.OXM_OF_ETH_SRC],
				table_id=1)
		datapath.send_msg(req)

	########################### SET GD DATA VARIABLE ############################################

		# req = bebaparser.OFPExpMsgHeaderFieldExtract(
		# 		datapath=datapath,
		# 		table_id=0,
		# 		extractor_id=0,
		# 		field=ofproto.OXM_OF_IPV4_SRC
		# 	)
		# datapath.send_msg(req)

		req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
				datapath=datapath,
				table_id=0,
				global_data_variable_id=0,
				value=313
			)
		datapath.send_msg(req)

		req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
				datapath=datapath,
				table_id=0,
				global_data_variable_id=2,
				value=22
			)
		datapath.send_msg(req)

		req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
				datapath=datapath,
				table_id=0,
				global_data_variable_id=4,
				value=44
			)
		datapath.send_msg(req)

		req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
				datapath=datapath,
				table_id=0,
				global_data_variable_id=5,
				value=55
			)
		datapath.send_msg(req)


########################### SET GD DATA VARIABLE ############################################

		req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
				datapath=datapath,
				table_id=1,
				global_data_variable_id=3,
				value=55
			)
		datapath.send_msg(req)

		########################### SET HF DATA VARIABLE TAB 1 ############################################
		# SI PUO FARE???


		''' HF[0] = OXM_OF_METADATA [id_pkt] '''
		req = bebaparser.OFPExpMsgHeaderFieldExtract(
				datapath=datapath,
				table_id=1,
				extractor_id=0,
				field=ofproto.OXM_OF_ETH_SRC
			)
		datapath.send_msg(req)

		# ''' HF[0] = OXM_OF_METADATA [id_pkt] '''
		# req = bebaparser.OFPExpMsgHeaderFieldExtract(
		# 		datapath=datapath,
		# 		table_id=1,
		# 		extractor_id=0,
		# 		field=bebaproto.OXM_EXP_STATE
		# 	)
		# datapath.send_msg(req)

		# aggiunta cosi tanto per fare un nuovo commit

		# ''' HF[0] = OXM_OF_METADATA [id_pkt] '''
		# req = bebaparser.OFPExpMsgHeaderFieldExtract(
		# 		datapath=datapath,
		# 		table_id=1,
		# 		extractor_id=0,
		# 		field=bebaproto.OXM_EXP_STATE
		# 	)
		# datapath.send_msg(req)


		''' #######################  TAB 0 NULLA  serve solo per i bug di OpenFlow, servono 2 stage xke le modifiche MPLS siano visibili'''
		# Non fa niente, ci sta solo per risolvere bug (presunti) di OpenFlow
		# match = ofparser.OFPMatch(condition0=0)
		# actions = [bebaparser.OFPExpActionSetState(state=1, table_id=0),
		# 			ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)]
		# inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
		# mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0,
		# 						priority=0, match=match, instructions=inst)
		# datapath.send_msg(mod)

		# match = ofparser.OFPMatch()#condition0=1)
		# actions = [bebaparser.OFPExpActionSetState(state=1, table_id=0),
		# 			bebaparser.OFPExpActionSetDataVariable(table_id=0, port_id=1, opcode=bebaproto.OPCODE_SUM, output_mem_pd_id=0, operand_1_mem_pd_id=1, operand_2_mem_pd_id=1),
		# 			# bebaparser.OFPExpActionWriteContextToField(src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,src_id=0,dst_field=ofproto.OXM_OF_MPLS_LABEL),
		# 			bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_gd_id=3, operand_1_hf_id=0, operand_2_cost=0),
		# 			ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)]
		# inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
		# mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0,
		# 						priority=0, match=match, instructions=inst)
		# datapath.send_msg(mod)

		# match = ofparser.OFPMatch(eth_type=0x0800 ,ipv4_src=('10.0.0.0','255.255.255.0'))

		match = ofparser.OFPMatch()
		actions = [bebaparser.OFPExpActionSetState(state=1, table_id=0),
					# bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_hf_id=0, operand_2_cost=3)]
					# bebaparser.OFPExpActionSetDataVariable(table_id=0, opcode=bebaproto.OPCODE_SUM, output_fd_id=2, operand_1_gd_id=0, operand_2_gd_id=2)]
					bebaparser.OFPExpActionWriteContextToField(src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,src_id=0,dst_field=ofproto.OXM_OF_METADATA)]
		inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions),
				# ofparser.OFPInstructionWriteMetadata(metadata=13, metadata_mask=0xFFFFFFFF),
				ofparser.OFPInstructionGotoTable(1)]
		mod = ofparser.OFPFlowMod(datapath=datapath, table_id=0,
								priority=0, match=match, instructions=inst)
		datapath.send_msg(mod)


		''' #######################  TAB 1   '''


		match = ofparser.OFPMatch()#state=2)
		actions = [bebaparser.OFPExpActionSetState(state=2, table_id=1),
					bebaparser.OFPExpActionSetDataVariable(table_id=1, opcode=bebaproto.OPCODE_SUM, output_fd_id=1, operand_1_hf_id=0, operand_2_cost=1),
					ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)]
					# bebaparser.OFPExpActionSetDataVariable(table_id=1, opcode=bebaproto.OPCODE_SUM, output_gd_id=0, operand_1_gd_id=1, operand_2_cost=3)]
		inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
		mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1,
								priority=10, match=match, instructions=inst)
		datapath.send_msg(mod)


		# match = ofparser.OFPMatch(metadata=313)
		# actions = [bebaparser.OFPExpActionSetState(state=2, table_id=1),
		# 			bebaparser.OFPExpActionSetDataVariable(table_id=1, opcode=bebaproto.OPCODE_SUM, output_gd_id=0, operand_1_gd_id=3, operand_2_cost=3)]
		# inst = [ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]
		# mod = ofparser.OFPFlowMod(datapath=datapath, table_id=1,
		# 						priority=0, match=match, instructions=inst)
		# datapath.send_msg(mod)


		# # for each input port, for each state
		# for i in range(1, N+1):
		# 	for s in range(N+1):
		# 		match = ofparser.OFPMatch(in_port=i, state=s)
		# 		if s == 0:
		# 			out_port = ofproto.OFPP_FLOOD
		# 		else:
		# 			out_port = s
		# 		actions = [bebaparser.OFPExpActionSetState(state=i, table_id=0, hard_timeout=10),
		# 					ofparser.OFPActionOutput(out_port)]
		# 		self.add_flow(datapath=datapath, table_id=0, priority=0,
		# 						match=match, actions=actions)

		""" Need to drop some packets for DEMO puporses only (avoid learning before manual send_eth)"""
示例#19
0
    def install_leaves(self, datapath):
        ##################################### TABLE 0: DISPATCHING ##################################################

        ######################### TABLE 0 CONFIG ###############
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=0,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {eth_dst} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=0)
        datapath.send_msg(req)
        """ Set update extractor = {eth_dst}  """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=0)
        datapath.send_msg(req)
        """ Field extractor for mpls label """
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=0,
            extractor_id=0,
            field=ofproto.OXM_OF_MPLS_LABEL)
        datapath.send_msg(req)
        """ Field extractor for timestamp """
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=0,
            extractor_id=1,
            field=bebaproto.OXM_EXP_TIMESTAMP)
        datapath.send_msg(req)
        """ Packet counter_max for designing probe frequency """
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=0, global_data_variable_id=0, value=9)
        datapath.send_msg(req)
        """ Condition C0: if counter reaches counter_max, then trigger probe sending """
        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            table_id=0,
            condition_id=0,
            condition=bebaproto.CONDITION_GTE,
            operand_1_fd_id=0,
            operand_2_gd_id=0)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            table_id=0,
            condition_id=3,
            condition=bebaproto.CONDITION_GTE,
            operand_1_fd_id=0,
            operand_2_gd_id=0)
        datapath.send_msg(req)

        ##################################### TABLE 0 FLOWS ##################################################
        """ RECEIVE PROBE ACTION """
        """ When a probe is received tab0 sends it to tab3"""
        """ match: 	MPLS """
        """ no action """
        """ instruction: goto tab3"""

        match = ofparser.OFPMatch(eth_type=0x8847)
        instructions = [ofparser.OFPInstructionGotoTable(3)]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=200,
                                  match=match,
                                  instructions=instructions)
        datapath.send_msg(mod)

        for i in UPPER_PORTS:
            """ Writes metadata 1 if C0 is true (i.e. if it's time to send probe) to inform the Util Table (2) """
            match = ofparser.OFPMatch(in_port=i, condition0=1)
            actions = [
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUB,
                    output_fd_id=0,
                    operand_1_fd_id=0,
                    operand_2_gd_id=0),
                ofparser.OFPActionPushMpls()
            ]  #push mpls for tab 2
            instructions = [
                ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                               actions),
                ofparser.OFPInstructionWriteMetadata(metadata=1,
                                                     metadata_mask=0xffffffff),
                ofparser.OFPInstructionGotoTable(2)
            ]
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      table_id=0,
                                      priority=50,
                                      match=match,
                                      instructions=instructions)
            datapath.send_msg(mod)
            """ If C0 is false, update the counter (i++) and go to Util Table for ewma measuring """
            match = ofparser.OFPMatch(in_port=i, condition0=0)
            actions = [
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=0,
                    operand_1_fd_id=0,
                    operand_2_cost=1)
            ]
            instructions = [
                ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                               actions),
                ofparser.OFPInstructionGotoTable(2)
            ]
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      table_id=0,
                                      priority=30,
                                      match=match,
                                      instructions=instructions)
            datapath.send_msg(mod)
        """ For packets from down ports (attached to hosts): go to ToR Discovery table (1) """
        for i in DOWN_PORTS:
            match = ofparser.OFPMatch(in_port=i)
            instructions = [ofparser.OFPInstructionGotoTable(1)]
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      table_id=0,
                                      priority=0,
                                      match=match,
                                      instructions=instructions)
            datapath.send_msg(mod)

        for i in [0, 1]:
            match = ofparser.OFPMatch(in_port=3,
                                      eth_type=0x0800,
                                      ip_proto=6,
                                      tcp_dst=10000 + i)
            actions = [ofparser.OFPActionOutput(i + 1)]
            self.add_flow(datapath=datapath,
                          table_id=0,
                          priority=200,
                          match=match,
                          actions=actions)

            match = ofparser.OFPMatch(in_port=3,
                                      eth_type=0x0800,
                                      ip_proto=6,
                                      tcp_src=10000 + i)
            actions = [ofparser.OFPActionOutput(i + 1)]
            self.add_flow(datapath=datapath,
                          table_id=0,
                          priority=200,
                          match=match,
                          actions=actions)

        ######################## TABLE 1 ToR DISCOVERY  #########################################################

        # this cycle writes metadata specifying to which leaf belongs the packet
        for i in LEAVES:
            if (i != datapath.id):
                match = ofparser.OFPMatch(eth_dst=MAC_ADDRS[i - 1])
                instructions = [
                    ofparser.OFPInstructionWriteMetadata(
                        metadata=i, metadata_mask=0xffffffff),
                    ofparser.OFPInstructionGotoTable(3)
                ]
                mod = ofparser.OFPFlowMod(datapath=datapath,
                                          table_id=1,
                                          priority=0,
                                          match=match,
                                          instructions=instructions)
                datapath.send_msg(mod)

        ######################### TABLE 2: ACTIVE PROBING ######################################################

        ################### TABLE 2 CONFIG #########

        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=2,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {IN_PORT} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=2)
        datapath.send_msg(req)
        """ Set update extractor = {IN_PORT}  """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=2)
        datapath.send_msg(req)
        # multiply factor: convert to kbit/s
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=2,
            global_data_variable_id=0,
            value=8000)
        datapath.send_msg(req)

        # number of averaging samples
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=2, global_data_variable_id=3, value=40)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=2,
            extractor_id=1,
            field=bebaproto.OXM_EXP_TIMESTAMP)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=2,
            extractor_id=2,
            field=bebaproto.OXM_EXP_PKT_LEN)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            condition=bebaproto.CONDITION_GTE,
            condition_id=0,
            table_id=2,
            operand_1_fd_id=4,
            operand_2_gd_id=3)
        datapath.send_msg(req)

        ############################### TABLE 2 FLOWS #############################
        """ For every packet coming from spine ports, calculates ewma """
        for i in UPPER_PORTS:
            #simply ewma measuring
            match = ofparser.OFPMatch(in_port=i, condition0=1)
            actions_ewma_1 = [  #calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUB,
                    output_fd_id=1,
                    operand_1_hf_id=1,
                    operand_2_fd_id=0),
                #calculates rate: R = (bytes / deltaT_us) * 1000 kB/s
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_MUL,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_gd_id=0),
                #stores the result in FDV[3]: THE FLOW ESTIMATED RATE
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_DIV,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_fd_id=1),
                #calculates ewma
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_EWMA,
                    output_fd_id=3,
                    operand_1_fd_id=3,
                    operand_2_cost=bebaproto.EWMA_PARAM_0250,
                    operand_3_fd_id=2),
                #saves current timestamp
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=0,
                    operand_1_hf_id=1,
                    operand_2_cost=0),
                #counter returns to zero
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUB,
                    output_fd_id=4,
                    operand_1_fd_id=4,
                    operand_2_fd_id=4),
                # saves in GDV[i] the ewma
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUM,
                    output_gd_id=i,
                    operand_1_fd_id=3,
                    operand_2_cost=0)
            ]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=30,
                          match=match,
                          actions=actions_ewma_1 +
                          [ofparser.OFPActionOutput(3)])

            match = ofparser.OFPMatch(in_port=i, condition0=0)
            actions_ewma_2 = [
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_hf_id=2),
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=4,
                    operand_1_fd_id=4,
                    operand_2_cost=1)
            ]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=30,
                          match=match,
                          actions=actions_ewma_2 +
                          [ofparser.OFPActionOutput(3)])
            """ PROBES: When it matches metadata=1 it means that this packet has to be duplicated to piggyback on it the probe """

            #group mod for packet duplication and probing
            buckets = []
            actions1 = [
                ofparser.OFPActionSetField(mpls_tc=datapath.id),  #the GDV[i]
                bebaparser.OFPExpActionWriteContextToField(
                    src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                    src_id=i,
                    dst_field=ofproto.OXM_OF_MPLS_LABEL),
                ofparser.OFPActionOutput(ofproto.OFPP_IN_PORT)
            ]
            buckets.append(ofparser.OFPBucket(actions=actions1))

            actions1 = [
                ofparser.OFPActionSetField(
                    mpls_tc=datapath.id),  #the GDV[other]
                bebaparser.OFPExpActionWriteContextToField(
                    src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                    src_id=(1 if i == 2 else 2),
                    dst_field=ofproto.OXM_OF_MPLS_LABEL),
                ofparser.OFPActionOutput((1 if i == 2 else 2))
            ]
            buckets.append(ofparser.OFPBucket(actions=actions1))

            req = ofparser.OFPGroupMod(datapath=datapath,
                                       type_=ofproto.OFPGT_ALL,
                                       group_id=i,
                                       buckets=buckets)
            datapath.send_msg(req)

            # actual match and actions: group action, popMpls() and output(3)
            match = ofparser.OFPMatch(in_port=i, eth_type=0x8847, metadata=1)
            actions = [
                ofparser.OFPActionGroup(i),
                ofparser.OFPActionPopMpls(),
                ofparser.OFPActionOutput(3)
            ]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=100,
                          match=match,
                          actions=actions)

            for j in [0, 1]:
                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x0800,
                                          ip_proto=6,
                                          tcp_dst=10000 + j,
                                          condition0=1)
                actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)]
                self.add_flow(datapath=datapath,
                              table_id=2,
                              priority=150,
                              match=match,
                              actions=actions)

                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x0800,
                                          ip_proto=6,
                                          tcp_src=10000 + j,
                                          condition0=1)
                actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)]
                self.add_flow(datapath=datapath,
                              table_id=2,
                              priority=150,
                              match=match,
                              actions=actions)

                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x0800,
                                          ip_proto=6,
                                          tcp_dst=10000 + j,
                                          condition0=0)
                actions = actions_ewma_2 + [ofparser.OFPActionOutput(3)]
                self.add_flow(datapath=datapath,
                              table_id=2,
                              priority=150,
                              match=match,
                              actions=actions)

                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x0800,
                                          ip_proto=6,
                                          tcp_src=10000 + j,
                                          condition0=0)
                actions = actions_ewma_2 + [ofparser.OFPActionOutput(3)]
                self.add_flow(datapath=datapath,
                              table_id=2,
                              priority=150,
                              match=match,
                              actions=actions)

        ######################## TABLE 3: FORWARDING ##############################################################

        ######################## TABLE 3 CONFIG #####################################################################

        ##### GDV[1] contains path utilization to dest 1 on port 1
        ##### GDV[2] contains path utilization to dest 2 on port 1
        ##### GDV[3] contains path utilization to dest 1 on port 2
        ##### GDV[4] contains path utilization to dest 2 on port 2

        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=3,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {ETH_DST IP_PROTO TCP_DST} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[
                ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST,
                ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST
            ],
            table_id=3)
        datapath.send_msg(req)
        """ Set update extractor = {}  """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[
                ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST,
                ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST
            ],
            table_id=3)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=0,
            field=ofproto.OXM_OF_MPLS_LABEL)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=1,
            field=bebaproto.OXM_EXP_TIMESTAMP)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=2,
            field=bebaproto.OXM_EXP_PKT_LEN)
        datapath.send_msg(req)

        # GDV[0] = multiply factor
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=3,
            global_data_variable_id=0,
            value=8000)
        datapath.send_msg(req)

        # GDV[6] = packets needed for average
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=3,
            global_data_variable_id=6,
            value=40 - 1)
        datapath.send_msg(req)

        # GDV[5] = elephant flow threshold
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=3,
            global_data_variable_id=5,
            value=2000)  # 2000 kb/s
        datapath.send_msg(req)

        # Lower flow threshold
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=3,
            global_data_variable_id=7,
            value=300)
        datapath.send_msg(req)

        for i in [1, 2, 3]:
            req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
                datapath=datapath,
                table_id=3,
                global_data_variable_id=i,
                value=0)
            datapath.send_msg(req)

        #################################### TABLE 3 FLOWS ###################################

        # many conditions as the number of LEAVES-1
        # for i in LEAVES except datapath.id: create condition[i]

        # in the case of 2 Spines. For more spines the configuration becomes more complex
        for destLeaf in [1, 2]:
            # C[destinationLeaf]: which port is less utilized?
            req = bebaparser.OFPExpMsgSetCondition(
                datapath=datapath,
                condition=bebaproto.CONDITION_LTE,
                condition_id=destLeaf,
                table_id=3,
                operand_1_gd_id=destLeaf,
                operand_2_gd_id=destLeaf + 2)
            datapath.send_msg(req)

        # C[0], has the flow exceeded threshold? i.e. flow_rate >= threshold => FDV[3] >= GDV[5]
        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            condition=bebaproto.CONDITION_GTE,
            condition_id=0,
            table_id=3,
            operand_1_fd_id=3,
            operand_2_gd_id=5)
        datapath.send_msg(req)

        # C[3], is the other flow lower than a value? FDV[4] < GDV[7] ?
        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            condition=bebaproto.CONDITION_LTE,
            condition_id=3,
            table_id=3,
            operand_1_fd_id=4,
            operand_2_gd_id=7)
        datapath.send_msg(req)

        # C[4]: did the counter reach counterMax? FDV[5] = GDV[6] ?
        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            condition=bebaproto.CONDITION_EQ,
            condition_id=4,
            table_id=3,
            operand_1_fd_id=5,
            operand_2_gd_id=6)
        datapath.send_msg(req)

        # leaf number dependent flows
        if datapath.id == 1:
            #LEAF 1 new flows: fetch the destination leaf and check the appropriate condition
            match1true = ofparser.OFPMatch(metadata=2, condition1=1,
                                           state=0)  #dst=2, port 1
            match2true = ofparser.OFPMatch(metadata=3, condition2=1,
                                           state=0)  #dst=3, port 1
            match1false = ofparser.OFPMatch(metadata=2, condition1=0,
                                            state=0)  #dst=2, port 2
            match2false = ofparser.OFPMatch(metadata=3, condition2=0,
                                            state=0)  #dst=3, port 2
        elif datapath.id == 2:
            #LEAF 2 new flows: fetch the destination leaf and check the appropriate condition
            match1true = ofparser.OFPMatch(metadata=1, condition1=1,
                                           state=0)  #dst=1, port 1
            match2true = ofparser.OFPMatch(metadata=3, condition2=1,
                                           state=0)  #dst=3, port 1
            match1false = ofparser.OFPMatch(metadata=1, condition1=0,
                                            state=0)  #dst=1, port 2
            match2false = ofparser.OFPMatch(metadata=3, condition2=0,
                                            state=0)  #dst=3, port 2
        elif datapath.id == 3:
            #LEAF 3 new flows: fetch the destination leaf and check the appropriate condition
            match1true = ofparser.OFPMatch(metadata=1, condition1=1,
                                           state=0)  #dst=1, port 1
            match2true = ofparser.OFPMatch(metadata=2, condition2=1,
                                           state=0)  #dst=2, port 1
            match1false = ofparser.OFPMatch(metadata=1, condition1=0,
                                            state=0)  #dst=1, port 2
            match2false = ofparser.OFPMatch(metadata=2, condition2=0,
                                            state=0)  #dst=2, port 2

        #if port 1 is better, set_state(1) and output 1
        actions_true = [
            bebaparser.OFPExpActionSetState(state=1,
                                            table_id=3,
                                            idle_timeout=5),
            ofparser.OFPActionOutput(1)
        ]
        #if port 2 is better, set_state(2) and output 2
        actions_false = [
            bebaparser.OFPExpActionSetState(state=2,
                                            table_id=3,
                                            idle_timeout=5),
            ofparser.OFPActionOutput(2)
        ]

        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=20,
                      match=match1true,
                      actions=actions_true)
        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=20,
                      match=match2true,
                      actions=actions_true)
        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=20,
                      match=match1false,
                      actions=actions_false)
        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=20,
                      match=match2false,
                      actions=actions_false)
        """ extract external probes' data and store in GDVs """

        match = ofparser.OFPMatch(eth_type=0x8847, mpls_tc=datapath.id)
        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=300,
                      match=match,
                      actions=[])

        for i in UPPER_PORTS:
            for leafNo in LEAVES:
                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x8847,
                                          mpls_tc=leafNo)
                """ actions: save in GDVs external probes' data """
                if datapath.id == 1:
                    if leafNo == 2:
                        actions = [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_gd_id=(1 if i == 1 else 3),
                                operand_1_hf_id=0,
                                operand_2_cost=0)
                        ]
                    elif leafNo == 3:
                        actions = [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_gd_id=(2 if i == 1 else 4),
                                operand_1_hf_id=0,
                                operand_2_cost=0)
                        ]
                elif datapath.id == 2:
                    if leafNo == 1:
                        actions = [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_gd_id=(1 if i == 1 else 3),
                                operand_1_hf_id=0,
                                operand_2_cost=0)
                        ]
                    elif leafNo == 3:
                        actions = [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_gd_id=(2 if i == 1 else 4),
                                operand_1_hf_id=0,
                                operand_2_cost=0)
                        ]
                elif datapath.id == 3:
                    if leafNo == 1:
                        actions = [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_gd_id=(1 if i == 1 else 3),
                                operand_1_hf_id=0,
                                operand_2_cost=0)
                        ]
                    elif leafNo == 2:
                        actions = [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_gd_id=(2 if i == 1 else 4),
                                operand_1_hf_id=0,
                                operand_2_cost=0)
                        ]

                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=200,
                              match=match,
                              actions=actions)

        for s in UPPER_PORTS:
            for metadata in LEAVES:
                # normal conditions, installed flows continue flowing, calculates ewma if counter reaches max
                match = ofparser.OFPMatch(in_port=3,
                                          state=s,
                                          metadata=metadata,
                                          condition4=1)
                actions_ewma = [  #calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST
                    bebaparser.OFPExpActionSetDataVariable(
                        table_id=3,
                        opcode=bebaproto.OPCODE_SUB,
                        output_fd_id=1,
                        operand_1_hf_id=1,
                        operand_2_fd_id=0),
                    #calculates rate: R = (bytes / deltaT_us) * 1000 kB/s
                    bebaparser.OFPExpActionSetDataVariable(
                        table_id=3,
                        opcode=bebaproto.OPCODE_MUL,
                        output_fd_id=2,
                        operand_1_fd_id=2,
                        operand_2_gd_id=0),
                    #stores the result in FDV[3]: THE FLOW ESTIMATED RATE
                    bebaparser.OFPExpActionSetDataVariable(
                        table_id=3,
                        opcode=bebaproto.OPCODE_DIV,
                        output_fd_id=2,
                        operand_1_fd_id=2,
                        operand_2_fd_id=1),
                    #calculates ewma
                    bebaparser.OFPExpActionSetDataVariable(
                        table_id=3,
                        opcode=bebaproto.OPCODE_EWMA,
                        output_fd_id=3,
                        operand_1_fd_id=3,
                        operand_2_cost=bebaproto.EWMA_PARAM_0250,
                        operand_3_fd_id=2),
                    #saves current timestamp
                    bebaparser.OFPExpActionSetDataVariable(
                        table_id=3,
                        opcode=bebaproto.OPCODE_SUM,
                        output_fd_id=0,
                        operand_1_hf_id=1,
                        operand_2_cost=0),
                    #counter returns to zero
                    bebaparser.OFPExpActionSetDataVariable(
                        table_id=3,
                        opcode=bebaproto.OPCODE_SUB,
                        output_fd_id=5,
                        operand_1_fd_id=5,
                        operand_2_fd_id=5)
                ]

                # FDV[4] = flow's alternative path utilization
                if datapath.id == 1:
                    if metadata == 2:
                        actions_ewma += [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_fd_id=4,
                                operand_1_gd_id=(1 if s == 2 else 3),
                                operand_2_cost=0)
                        ]
                    elif metadata == 3:
                        actions_ewma += [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_fd_id=4,
                                operand_1_gd_id=(2 if s == 2 else 4),
                                operand_2_cost=0)
                        ]
                elif datapath.id == 2:
                    if metadata == 1:
                        actions_ewma += [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_fd_id=4,
                                operand_1_gd_id=(1 if s == 2 else 3),
                                operand_2_cost=0)
                        ]
                    elif metadata == 3:
                        actions_ewma += [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_fd_id=4,
                                operand_1_gd_id=(2 if s == 2 else 4),
                                operand_2_cost=0)
                        ]
                elif datapath.id == 3:
                    if metadata == 1:
                        actions_ewma += [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_fd_id=4,
                                operand_1_gd_id=(1 if s == 2 else 3),
                                operand_2_cost=0)
                        ]
                    elif metadata == 2:
                        actions_ewma += [
                            bebaparser.OFPExpActionSetDataVariable(
                                table_id=3,
                                opcode=bebaproto.OPCODE_SUM,
                                output_fd_id=4,
                                operand_1_gd_id=(2 if s == 2 else 4),
                                operand_2_cost=0)
                        ]
                actions = actions_ewma + [ofparser.OFPActionOutput(s)]
                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=30,
                              match=match,
                              actions=actions)
                # normal conditions
                match = ofparser.OFPMatch(in_port=3,
                                          state=s,
                                          metadata=metadata,
                                          condition4=0)
                actions_ewma_bg = [
                    bebaparser.OFPExpActionSetDataVariable(
                        table_id=3,
                        opcode=bebaproto.OPCODE_SUM,
                        output_fd_id=2,
                        operand_1_fd_id=2,
                        operand_2_hf_id=2),
                    bebaparser.OFPExpActionSetDataVariable(
                        table_id=3,
                        opcode=bebaproto.OPCODE_SUM,
                        output_fd_id=5,
                        operand_1_fd_id=5,
                        operand_2_cost=1)
                ]
                actions = actions_ewma_bg + [ofparser.OFPActionOutput(s)]
                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=30,
                              match=match,
                              actions=actions)

                ########### match for extended states: same thing as in normal states but evaluate condition0 ##########
                match = ofparser.OFPMatch(in_port=3,
                                          state=s + (1 << 5),
                                          metadata=metadata,
                                          condition0=1,
                                          condition4=1)
                actions = actions_ewma + [ofparser.OFPActionOutput(s)]
                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=35,
                              match=match,
                              actions=actions)

                match = ofparser.OFPMatch(in_port=3,
                                          state=s + (1 << 5),
                                          metadata=metadata,
                                          condition0=1,
                                          condition4=0)
                actions = actions_ewma_bg + [ofparser.OFPActionOutput(s)]
                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=35,
                              match=match,
                              actions=actions)

                ############# condition[0] and [3] are verified, (i.e. big flow) change port ###########
                match = ofparser.OFPMatch(in_port=3,
                                          state=s,
                                          condition0=1,
                                          condition3=1)
                actions = [
                    bebaparser.OFPExpActionSetState(
                        state=(1 if s == 2 else 2) + (1 << 5),
                        table_id=3,
                        idle_timeout=5),
                    ofparser.OFPActionOutput(1 if s == 2 else 2)
                ]
                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=40,
                              match=match,
                              actions=actions)

                ########### if the flow returns to a rate under the threshold #############################
                match = ofparser.OFPMatch(in_port=3,
                                          state=s + (1 << 5),
                                          condition0=0)
                actions = [
                    bebaparser.OFPExpActionSetState(state=s,
                                                    table_id=3,
                                                    idle_timeout=5),
                    ofparser.OFPActionOutput(s)
                ]
                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=50,
                              match=match,
                              actions=actions)
示例#20
0
"""
Make rules that form a diamond of dependencies




"""

flows = [
    # Table 0
    parser.OFPFlowStats(
        table_id=0,
        priority=10,
        match=parser.OFPMatch(vlan_vid=(0x1000, 0x1FFE)),
        instructions=[
            parser.OFPInstructionGotoTable(1)
        ]
    ),
    parser.OFPFlowStats(
        table_id=0,
        priority=10,
        match=parser.OFPMatch(vlan_vid=(0x1002, 0x1FFE)),
        instructions=[
            parser.OFPInstructionGotoTable(1)
        ]
    ),
    parser.OFPFlowStats(
        table_id=0,
        priority=0,
        match=parser.OFPMatch(),
        instructions=[]
示例#21
0
"""

flows = [
    # Table 0
    parser.OFPFlowStats(table_id=0,
                        priority=1000,
                        match=parser.OFPMatch(tcp_dst=80),
                        instructions=[]),
    parser.OFPFlowStats(table_id=0,
                        priority=1000,
                        match=parser.OFPMatch(tcp_dst=443),
                        instructions=[]),
    parser.OFPFlowStats(table_id=0,
                        priority=0,
                        match=parser.OFPMatch(),
                        instructions=[parser.OFPInstructionGotoTable(1)]),

    # Table 1
    parser.OFPFlowStats(table_id=1,
                        priority=1000,
                        match=parser.OFPMatch(eth_dst=1),
                        instructions=[parser.OFPInstructionGotoTable(2)]),
    parser.OFPFlowStats(table_id=1,
                        priority=1000,
                        match=parser.OFPMatch(eth_dst=2),
                        instructions=[parser.OFPInstructionGotoTable(2)]),
    parser.OFPFlowStats(table_id=1,
                        priority=0,
                        match=parser.OFPMatch(),
                        instructions=[parser.OFPInstructionGotoTable(3)]),
示例#22
0
    def load_fsm(self, datapath):
        LOG.info("Loading Table 1 FSM ...")
        ##=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
        ## INIT - ANY
        """
        Match firstly incoming packets.
       
        The actual version is little bit hacked, all incomming flows
        are forwarded to the table 2 which is performed counting of all incomming data.         

        (TODO - remove eth_type and ip_proto?)
        """
        match = ofparser.OFPMatch(eth_type=0x0800, ip_proto=6, state=self.INIT)

        actions = [
            osparser.OFPExpActionSetState(
                state=self.ACTIVE,
                table_id=1,
                # TODO - TIMEOUTS
                idle_timeout=1)
        ]
        #inst = [ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)]
        inst = [
            ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions),
            ofparser.OFPInstructionGotoTable(table_id=2)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=1,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        ##=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
        ## ACTIVE - ANY
        """
        Match other incoming packets. Need this state since we do not want to
        refresh timeouts of flow entry.

        (TODO - remove eth_type and ip_proto?)
        """
        match = ofparser.OFPMatch(eth_type=0x0800,
                                  ip_proto=6,
                                  state=self.ACTIVE)
        """
        TODO - simplify ... remove useless stuff
        """
        actions = []
        #inst = [ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)]
        inst = [
            ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions),
            ofparser.OFPInstructionGotoTable(table_id=2)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=1,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        LOG.info("Done.")
示例#23
0
    def function_dynamic_nat(self, datapath):
        """ Set table 1 as stateful """
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=1,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set table 2 restore """
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=2,
                                                         stateful=1)
        datapath.send_msg(req)

        ############################### LOOKUP/UPDATE ###################################
        """ Tab1 """
        """ Set lookup extractor = {OXM_OF_METADATA} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_METADATA],
            table_id=1)
        datapath.send_msg(req)
        """ Set update extractor = {OXM_OF_METADATA}  """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_METADATA],
            table_id=1)
        datapath.send_msg(req)
        """ Tab2 """
        """ Set lookup extractor = {OXM_OF_IPV4_SRC, OXM_OF_IP_PROTO, OXM_OF_TCP_SRC} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[
                ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IP_PROTO,
                ofproto.OXM_OF_TCP_SRC
            ],
            table_id=2)
        datapath.send_msg(req)
        """ Set lookup extractor = {OXM_OF_IPV4_DST, OXM_OF_IP_PROTO, OXM_OF_TCP_DST} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[
                ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_IP_PROTO,
                ofproto.OXM_OF_TCP_DST
            ],
            table_id=2)
        datapath.send_msg(req)
        """ Tab3 """

        ########################### SET STATE TABLE 1 ############################################

        for stateVal in range(1, 21):
            state = bebaparser.OFPExpMsgSetFlowState(
                datapath=datapath,
                state=2000 + stateVal,
                keys=[stateVal, 0, 0, 0, 0, 0, 0, 0],
                table_id=1)
            datapath.send_msg(state)

        ########################### SET HF DATA VARIABLE TAB 1 ############################################
        ''' GD[0] = state_label'''
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=1, global_data_variable_id=0, value=0)
        datapath.send_msg(req)
        ''' HF[0] = OXM_EXP_STATE [state_label] '''
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=1,
            extractor_id=0,
            field=bebaproto.OXM_EXP_STATE)
        datapath.send_msg(req)

        ########################### SET HF DATA VARIABLE TAB 2 ############################################
        ''' HF[0] = OXM_OF_IPV4_SRC [id_pkt] '''
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=2,
            extractor_id=0,
            field=ofproto.OXM_OF_IPV4_SRC)
        datapath.send_msg(req)
        ''' HF[1] = OXM_OF_TCP_SRC [id_pkt] '''
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=2,
            extractor_id=1,
            field=ofproto.OXM_OF_TCP_SRC)
        datapath.send_msg(req)

        ########################### SET HF DATA VARIABLE TAB 3 ############################################
        ''' HF[0] = OXM_OF_METADATA [metadata] '''
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=0,
            field=ofproto.OXM_OF_METADATA)
        datapath.send_msg(req)

        ################################# REGOLE ############################################
        ''' #######################  TAB 0  '''

        match = ofparser.OFPMatch(state=0, in_port=LAN_PORT)
        actions = [
            bebaparser.OFPExpActionSetState(state=1, table_id=0),
            bebaparser.OFPExpActionSetDataVariable(table_id=0,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_gd_id=1,
                                                   operand_1_gd_id=1,
                                                   operand_2_cost=1),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                src_id=1,
                dst_field=ofproto.OXM_OF_METADATA)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(1)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=89,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 12
        match = ofparser.OFPMatch(state=1, in_port=LAN_PORT)
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(3)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=88,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 13
        match = ofparser.OFPMatch(state=0,
                                  in_port=INTERNET_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst='1.0.0.1')
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(2)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=87,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 1  '''

        # Line 0
        # HF[0] = state_label
        # GD[0] = state_label + 0 => GD[0] + HF[0]
        # state_label -> metadata => GD[0] = HF[0]
        match = ofparser.OFPMatch(in_port=3)
        actions = [
            bebaparser.OFPExpActionSetDataVariable(table_id=1,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_gd_id=0,
                                                   operand_1_hf_id=0,
                                                   operand_2_cost=0),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_METADATA)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(2)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=100,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 2 restore'''

        # Line 0
        # ip.src -> R0 => HF[0] -> FD[0] => FD[0] = HF[0] + 0
        # tcp.src -> R1 => HF[1] -> FD[1] => FD[1] = HF[1] + 0
        match = ofparser.OFPMatch(state=0, in_port=LAN_PORT)
        actions = [
            bebaparser.OFPExpActionSetState(state=1, table_id=2),
            bebaparser.OFPExpActionSetDataVariable(table_id=2,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=0,
                                                   operand_1_hf_id=0,
                                                   operand_2_cost=0),
            bebaparser.OFPExpActionSetDataVariable(table_id=2,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=1,
                                                   operand_1_hf_id=1,
                                                   operand_2_cost=0)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(3)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=2,
                                  priority=100,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 1
        # ip.dst = R0 => IPV4_DST = FD[0]
        # tcp.dst = R1 => TCP_DST = FD[1]
        match = ofparser.OFPMatch(state=1, in_port=INTERNET_PORT)
        actions = [
            bebaparser.OFPExpActionSetState(state=1, table_id=2),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_IPV4_DST),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                src_id=1,
                dst_field=ofproto.OXM_OF_TCP_DST)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=2,
                                  priority=99,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 3 translate '''

        # Line 3
        # metadata(b16,b31) -> R1 => metadata(b16,b31) -> FD[1] => FD[1] = HF[0]
        # ip.src = 10.0.0.1
        # tcp.src = R1 => TCP_SRC = FD[1]
        match = ofparser.OFPMatch(state=0, in_port=LAN_PORT, eth_type=0x0800)
        actions = [
            bebaparser.OFPExpActionSetState(state=1, table_id=3),
            bebaparser.OFPExpActionSetDataVariable(table_id=3,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=1,
                                                   operand_1_hf_id=0,
                                                   operand_2_cost=0),
            ofparser.OFPActionSetField(ipv4_src="1.0.0.1"),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                src_id=1,
                dst_field=ofproto.OXM_OF_TCP_SRC)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=3,
                                  priority=97,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 4
        # ip.src = 10.0.0.1
        # tcp.src = R1 => TCP_SRC = FD[1]
        match = ofparser.OFPMatch(state=1, in_port=LAN_PORT, eth_type=0x0800)
        actions = [
            bebaparser.OFPExpActionSetState(state=1, table_id=3),
            ofparser.OFPActionSetField(ipv4_src='1.0.0.1'),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                src_id=1,
                dst_field=ofproto.OXM_OF_TCP_SRC)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=3,
                                  priority=96,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
示例#24
0
    def function_load_balancer(self, datapath):
        """ Tab0 """
        """ Set lookup extractor = {BiFlow} """
        # GIA CONFIGURATA
        """ Set table 3 translate """
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=3,
                                                         stateful=1)
        datapath.send_msg(req)

        ############################### LOOKUP/UPDATE ###################################
        """ Tab3 """
        """ Set lookup extractor = {OXM_OF_IPV4_SRC, OXM_OF_TCP_SRC} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_TCP_SRC],
            table_id=3)
        datapath.send_msg(req)
        """ Set update extractor = {OXM_OF_IPV4_SRC, OXM_OF_TCP_SRC} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_TCP_SRC],
            table_id=3)
        datapath.send_msg(req)

        ########################### SET GD E HF DATA VARIABLE TAB 3 ############################################
        ''' GD[0] = 0'''
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=3, global_data_variable_id=0, value=0)
        datapath.send_msg(req)
        ''' GD[1] = LAN_DUE 10.0.0.2 hexadecimal'''
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=3,
            global_data_variable_id=1,
            value=0x0200000a)
        datapath.send_msg(req)
        ''' GD[2] = LAN_TRE 10.0.0.3 hexadecimal'''
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=3,
            global_data_variable_id=2,
            value=0x0300000a)
        datapath.send_msg(req)
        ''' GD[3] = PORT 80 '''
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=3,
            global_data_variable_id=3,
            value=0x5000)
        datapath.send_msg(req)

        ################################# RULES ############################################
        ''' #######################  TAB 0  '''

        # Line 7
        match = ofparser.OFPMatch(state=0,
                                  in_port=INTERNET_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst='1.0.0.1',
                                  ip_proto=6,
                                  tcp_dst=80)
        actions = [
            bebaparser.OFPExpActionSetState(state=1, table_id=0),
            bebaparser.OFPExpActionSetDataVariable(table_id=0,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_gd_id=0,
                                                   operand_1_gd_id=0,
                                                   operand_2_cost=1),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_METADATA)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(3)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=93,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 8
        match = ofparser.OFPMatch(state=1,
                                  in_port=INTERNET_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst='1.0.0.1',
                                  ip_proto=6,
                                  tcp_dst=80)
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(3)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=92,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 9
        match = ofparser.OFPMatch(state=0,
                                  in_port=LAN_PORT,
                                  eth_type=0x0800,
                                  ipv4_src='10.0.0.2',
                                  ip_proto=6,
                                  tcp_src=80)
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=91,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 10
        match = ofparser.OFPMatch(state=0,
                                  in_port=LAN_PORT,
                                  eth_type=0x0800,
                                  ipv4_src='10.0.0.3',
                                  ip_proto=6,
                                  tcp_src=80)
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=90,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 3 translate '''

        # Line 0
        # ip.dst = 10.0.0.2
        # tcp.dst = 80
        # 10.0.0.2 -> R0 => 10.0.0.2 -> FD[0] => FD[0] = GD[0] + 10.0.0.2 => 0 + 10.0.0.2
        # 80 -> R1 		 => 80 -> FD[1] 	  => GD[0] + 80 			  => 0 + 80
        match = ofparser.OFPMatch(state=0,
                                  in_port=INTERNET_PORT,
                                  metadata=(0, 0x000000001),
                                  eth_type=0x0800,
                                  ip_proto=6)
        actions = [
            bebaparser.OFPExpActionSetState(state=1, table_id=3),
            ofparser.OFPActionSetField(ipv4_dst='10.0.0.2'),
            ofparser.OFPActionSetField(tcp_dst=80),
            # tolto per test
            bebaparser.OFPExpActionSetDataVariable(table_id=3,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=0,
                                                   operand_1_gd_id=1,
                                                   operand_2_cost=0),
            bebaparser.OFPExpActionSetDataVariable(table_id=3,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=1,
                                                   operand_1_gd_id=0,
                                                   operand_2_cost=80)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=3,
                                  priority=100,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 1
        # ip.dst = 10.0.0.3
        # tcp.dst = 80
        # 10.0.0.3 -> R0 => 10.0.0.3 -> FD[0] => FD[0] = GD[0] + 10.0.0.3 => 0 + 10.0.0.3
        # 80 -> R1 		 => 80 -> FD[1] 	  => GD[0] + 80 			  => 0 + 80
        match = ofparser.OFPMatch(state=0,
                                  in_port=INTERNET_PORT,
                                  metadata=(1, 0x000000001),
                                  eth_type=0x0800,
                                  ip_proto=6)
        actions = [
            bebaparser.OFPExpActionSetState(state=1, table_id=3),
            ofparser.OFPActionSetField(ipv4_dst='10.0.0.3'),
            ofparser.OFPActionSetField(tcp_dst=80),
            # tolto per test
            bebaparser.OFPExpActionSetDataVariable(table_id=3,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=0,
                                                   operand_1_gd_id=2,
                                                   operand_2_cost=0),
            bebaparser.OFPExpActionSetDataVariable(table_id=3,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=1,
                                                   operand_1_gd_id=0,
                                                   operand_2_cost=80)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=3,
                                  priority=99,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 2
        # ip.dst = R0 => IPV4_DST = FD[0]
        # tcp.dst = R1 => TCP_DST = FD[1]
        match = ofparser.OFPMatch(state=1, in_port=INTERNET_PORT)
        actions = [
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_IPV4_DST),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                src_id=1,
                dst_field=ofproto.OXM_OF_TCP_DST)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=3,
                                  priority=98,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 4 forward '''

        # Line 4
        match = ofparser.OFPMatch(in_port=LAN_PORT,
                                  eth_type=0x0800,
                                  ipv4_src='10.0.0.2',
                                  ip_proto=6,
                                  tcp_src=80)
        actions = [
            ofparser.OFPActionSetField(ipv4_src='1.0.0.1'),
            ofparser.OFPActionSetField(tcp_src=80),
            ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:01"),
            ofparser.OFPActionOutput(INTERNET_PORT)
        ]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=96,
                      match=match,
                      actions=actions)

        # Line 5
        match = ofparser.OFPMatch(in_port=LAN_PORT,
                                  eth_type=0x0800,
                                  ipv4_src='10.0.0.3',
                                  ip_proto=6,
                                  tcp_src=80)
        actions = [
            ofparser.OFPActionSetField(ipv4_src='1.0.0.1'),
            ofparser.OFPActionSetField(tcp_src=80),
            ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:01"),
            ofparser.OFPActionOutput(INTERNET_PORT)
        ]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=95,
                      match=match,
                      actions=actions)

        # Line 6
        match = ofparser.OFPMatch()
        actions = [
            ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:01"),
            ofparser.OFPActionOutput(INTERNET_PORT)
        ]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=94,
                      match=match,
                      actions=actions)
示例#25
0
    def function_lan_dmz_isolation(self, datapath):
        """ Set table 0 as stateful """
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=0,
                                                         stateful=1)
        datapath.send_msg(req)

        ############################### LOOKUP/UPDATE ###################################
        """ Tab0 """
        """ Set lookup extractor = {BiFlow} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[
                ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST,
                ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST
            ],
            table_id=0,
            biflow=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {BiFlow} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[
                ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST,
                ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST
            ],
            table_id=0,
            biflow=1)
        datapath.send_msg(req)
        """ Tab4 """
        """ Stateless """

        ########################### SET GD DATA VARIABLE TAB 0 ############################################
        ''' GD[0] = 0'''
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=0, global_data_variable_id=0, value=0)
        datapath.send_msg(req)
        ''' GD[1] = 0 '''
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=0, global_data_variable_id=0, value=0)
        datapath.send_msg(req)

        ################################# REGOLE ############################################

        match = ofparser.OFPMatch(eth_type=0x0806)
        actions = [ofparser.OFPActionOutput(ofproto.OFPP_FLOOD)]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=100,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 0  '''
        # Line 0
        match = ofparser.OFPMatch(state=0,
                                  in_port=DMZ_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst=('10.0.0.0', '255.255.255.0'))
        actions = [bebaparser.OFPExpActionSetState(state=11, table_id=0)]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=0,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=100,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 1
        match = ofparser.OFPMatch(state=0,
                                  in_port=LAN_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst=('8.0.0.0', '255.255.255.0'))
        actions = [bebaparser.OFPExpActionSetState(state=12, table_id=0)]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=0,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=99,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 2
        match = ofparser.OFPMatch(state=11,
                                  in_port=DMZ_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst=('10.0.0.0', '255.255.255.0'))
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=0,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=98,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 3
        match = ofparser.OFPMatch(state=11,
                                  in_port=LAN_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst=('8.0.0.0', '255.255.255.0'))
        actions = [bebaparser.OFPExpActionSetState(state=2, table_id=0)]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=1,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=97,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 4
        match = ofparser.OFPMatch(state=12,
                                  in_port=LAN_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst=('8.0.0.0', '255.255.255.0'))
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=0,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=96,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 5
        match = ofparser.OFPMatch(state=12,
                                  in_port=DMZ_PORT,
                                  eth_type=0x0800,
                                  ipv4_dst=('10.0.0.0', '255.255.255.0'))
        actions = [bebaparser.OFPExpActionSetState(state=2, table_id=0)]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=1,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=95,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Line 6
        match = ofparser.OFPMatch(state=2)
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=1,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=94,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 1   '''
        # NOT USED IN THIS USE CASE
        ''' #######################  TAB 2 restore'''
        # NOT USED IN THIS USE CASE
        ''' #######################  TAB 3 translate '''
        # NOT USED IN THIS USE CASE
        ''' #######################  TAB 4 forward '''

        # Line 0
        match = ofparser.OFPMatch(in_port=DMZ_PORT,
                                  metadata=(0, 0x00000000F),
                                  eth_type=0x0800,
                                  ipv4_dst=('10.0.0.0', '255.255.255.0'))
        actions = []
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=100,
                      match=match,
                      actions=actions)

        # Line 1
        match = ofparser.OFPMatch(in_port=DMZ_PORT,
                                  metadata=(1, 0x00000000F),
                                  eth_type=0x0800,
                                  ipv4_dst='10.0.0.2')
        actions = [
            ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:03"),
            ofparser.OFPActionOutput(LAN_PORT)
        ]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=99,
                      match=match,
                      actions=actions)

        # Line 1 BIS
        match = ofparser.OFPMatch(in_port=DMZ_PORT,
                                  metadata=(1, 0x00000000F),
                                  eth_type=0x0800,
                                  ipv4_dst='10.0.0.3')
        actions = [
            ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:04"),
            ofparser.OFPActionOutput(LAN_PORT)
        ]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=99,
                      match=match,
                      actions=actions)

        # Line 2
        match = ofparser.OFPMatch(eth_type=0x0800, ipv4_dst='8.0.0.2')
        actions = [
            ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:02"),
            ofparser.OFPActionOutput(DMZ_PORT)
        ]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=98,
                      match=match,
                      actions=actions)

        # Line 3
        match = ofparser.OFPMatch(eth_type=0x0800, ipv4_dst='10.0.0.2')
        actions = [
            ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:03"),
            ofparser.OFPActionOutput(LAN_PORT)
        ]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=97,
                      match=match,
                      actions=actions)

        # Line 3 BIS
        match = ofparser.OFPMatch(eth_type=0x0800, ipv4_dst='10.0.0.3')
        actions = [
            ofparser.OFPActionSetField(eth_dst="00:00:00:00:00:04"),
            ofparser.OFPActionOutput(LAN_PORT)
        ]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=97,
                      match=match,
                      actions=actions)
    def install_spines(self, datapath):
        ######################### TABLE 1 CONFIG ###############
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=0,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {eth_dst} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=0)
        datapath.send_msg(req)
        """ Set update extractor = {eth_dst}  """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=0)
        datapath.send_msg(req)

        # mpls extractor
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=0,
            extractor_id=0,
            field=ofproto.OXM_OF_MPLS_LABEL)
        datapath.send_msg(req)

        # timestamp extractor
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=0,
            extractor_id=1,
            field=bebaproto.OXM_EXP_TIMESTAMP)
        datapath.send_msg(req)

        # packet length extractor
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=0,
            extractor_id=2,
            field=bebaproto.OXM_EXP_PKT_LEN)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            condition=bebaproto.CONDITION_GTE,
            condition_id=0,
            table_id=0,
            operand_1_hf_id=1,
            operand_2_fd_id=4)
        datapath.send_msg(req)

        ########################### TABLE 1: MEASURING #####################

        for i in LEAVES:
            if i == 1:
                out_ports = [2, 3]
            elif i == 2:
                out_ports = [1, 3]
            elif i == 3:
                out_ports = [1, 2]

            buckets = []
            actions = [
                bebaparser.OFPExpActionWriteContextToField(
                    src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                    src_id=4,
                    dst_field=ofproto.OXM_OF_MPLS_LABEL),
                ofparser.OFPActionOutput(out_ports[0])
            ]
            buckets.append(ofparser.OFPBucket(actions=actions))

            actions = [
                bebaparser.OFPExpActionWriteContextToField(
                    src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                    src_id=5,
                    dst_field=ofproto.OXM_OF_MPLS_LABEL),
                ofparser.OFPActionOutput(out_ports[1])
            ]
            buckets.append(ofparser.OFPBucket(actions=actions))

            # send the group action
            req = ofparser.OFPGroupMod(datapath=datapath,
                                       type_=ofproto.OFPGT_ALL,
                                       group_id=i,
                                       buckets=buckets)
            datapath.send_msg(req)

            match = ofparser.OFPMatch(in_port=i, eth_type=0x8847)
            actions = [
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUM,
                    output_gd_id=4,
                    operand_1_hf_id=0,
                    operand_2_gd_id=out_ports[0]),
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUM,
                    output_gd_id=5,
                    operand_1_hf_id=0,
                    operand_2_gd_id=out_ports[1]),
                ofparser.OFPActionGroup(i)
            ]
            self.add_flow(datapath=datapath,
                          priority=600,
                          table_id=0,
                          match=match,
                          actions=actions)

            # first packet of a flow
            match = ofparser.OFPMatch(state=0, in_port=i)
            actions = [
                bebaparser.OFPExpActionSetState(table_id=0,
                                                state=1,
                                                idle_timeout=2),
                # saves timestamp
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=4,
                    operand_1_hf_id=1,
                    operand_2_cost=PROBE_FREQ)
            ]
            insts = [
                ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                               actions),
                ofparser.OFPInstructionGotoTable(1)
            ]
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      table_id=0,
                                      priority=500,
                                      match=match,
                                      instructions=insts)
            datapath.send_msg(mod)

            # simple forwarding packets go to second table to forward
            match = ofparser.OFPMatch(state=1, in_port=i, condition0=1)
            actions = [  # calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUB,
                    output_fd_id=1,
                    operand_1_hf_id=1,
                    operand_2_fd_id=0),
                # calculates rate: R = (bytes / deltaT_ms) * 8 [kb/s]
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_MUL,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_cost=8),
                # stores the result in FDV[3]: THE FLOW ESTIMATED RATE
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_DIV,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_fd_id=1),
                # calculates ewma
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_EWMA,
                    output_fd_id=3,
                    operand_1_fd_id=3,
                    operand_2_cost=ALPHA,
                    operand_3_fd_id=2),
                # saves current timestamp
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=0,
                    operand_1_hf_id=1,
                    operand_2_cost=0),
                # saves timestamp + probe freq
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=4,
                    operand_1_hf_id=1,
                    operand_2_cost=PROBE_FREQ),
                # reset byte counter
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUB,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_fd_id=2),
                # saves in GDV[i] the ewma
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUM,
                    output_gd_id=i,
                    operand_1_fd_id=3,
                    operand_2_cost=0)
            ]
            instructions = [
                ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                               actions),
                ofparser.OFPInstructionGotoTable(1)
            ]
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      priority=0,
                                      table_id=0,
                                      match=match,
                                      instructions=instructions)
            datapath.send_msg(mod)

            match = ofparser.OFPMatch(state=1, in_port=i, condition0=0)
            actions = [
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=0,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_hf_id=2)
            ]
            instructions = [
                ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                               actions),
                ofparser.OFPInstructionGotoTable(1)
            ]
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      priority=0,
                                      table_id=0,
                                      match=match,
                                      instructions=instructions)
            datapath.send_msg(mod)

        ######################## TABLE 2: FORWARDING ################
        for i in LEAVES:
            match = ofparser.OFPMatch(eth_dst=MAC_ADDRS[i - 1])
            actions = [ofparser.OFPActionOutput(i)]
            self.add_flow(datapath=datapath,
                          table_id=1,
                          priority=0,
                          match=match,
                          actions=actions)
    def install_leaves(self, datapath):
        # Send probe packet to packet generation table
        req = bebaparser.OFPExpMsgAddPktTmp(datapath=datapath,
                                            pkttmp_id=0,
                                            pkt_data=pkt_raw)
        datapath.send_msg(req)

        ##################################### TABLE 0: DISPATCHING ##################################################

        ######################### TABLE 0 CONFIG ###############
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=0,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {eth_dst} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=0)
        datapath.send_msg(req)
        """ Set update extractor = {eth_dst}  """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=0)
        datapath.send_msg(req)
        """ Field extractor for mpls label """
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=0,
            extractor_id=0,
            field=ofproto.OXM_OF_MPLS_LABEL)
        datapath.send_msg(req)
        """ Field extractor for timestamp """
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=0,
            extractor_id=1,
            field=bebaproto.OXM_EXP_TIMESTAMP)
        datapath.send_msg(req)
        """ Packet counter_max for designing probe frequency """
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=0,
            global_data_variable_id=0,
            value=PROBE_FREQ)
        datapath.send_msg(req)
        """ Condition C0: if counter reaches counter_max, then trigger probe sending """
        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            table_id=0,
            condition_id=0,
            condition=bebaproto.CONDITION_GTE,
            operand_1_fd_id=0,
            operand_2_gd_id=0)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            table_id=0,
            condition_id=3,
            condition=bebaproto.CONDITION_GTE,
            operand_1_fd_id=0,
            operand_2_gd_id=0)
        datapath.send_msg(req)

        ##################################### TABLE 0 FLOWS ##################################################
        """ RECEIVE PROBE ACTION """
        """ When a probe is received tab0 sends it to tab3"""
        """ match: 	MPLS """
        """ no action """
        """ instruction: goto tab3"""

        match = ofparser.OFPMatch(eth_type=0x8847)
        instructions = [ofparser.OFPInstructionGotoTable(3)]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=200,
                                  match=match,
                                  instructions=instructions)
        datapath.send_msg(mod)
        """ For packets from down ports (attached to hosts): go to ToR Discovery table (1) """
        for i in DOWN_PORTS:
            match = ofparser.OFPMatch(in_port=i)
            instructions = [ofparser.OFPInstructionGotoTable(1)]
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      table_id=0,
                                      priority=10,
                                      match=match,
                                      instructions=instructions)
            datapath.send_msg(mod)

        match = ofparser.OFPMatch()
        instructions = [ofparser.OFPInstructionGotoTable(2)]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=0,
                                  match=match,
                                  instructions=instructions)
        datapath.send_msg(mod)

        # using low bitrate flows to refresh the estimates. For testing purposes only
        for i in [0, 1]:
            match = ofparser.OFPMatch(in_port=3,
                                      eth_type=0x0800,
                                      ip_proto=6,
                                      tcp_dst=10000 + i)
            actions = [ofparser.OFPActionOutput(i + 1)]
            self.add_flow(datapath=datapath,
                          table_id=0,
                          priority=200,
                          match=match,
                          actions=actions)

            match = ofparser.OFPMatch(in_port=3,
                                      eth_type=0x0800,
                                      ip_proto=6,
                                      tcp_src=10000 + i)
            actions = [ofparser.OFPActionOutput(i + 1)]
            self.add_flow(datapath=datapath,
                          table_id=0,
                          priority=200,
                          match=match,
                          actions=actions)

        ######################## TABLE 1 ToR DISCOVERY  #########################################################

        # this cycle writes metadata specifying to which leaf belongs the packet
        for i in LEAVES:
            if i != datapath.id:
                match = ofparser.OFPMatch(eth_dst=MAC_ADDRS[i - 1])
                instructions = [
                    ofparser.OFPInstructionWriteMetadata(
                        metadata=i, metadata_mask=0xffffffff),
                    ofparser.OFPInstructionGotoTable(3)
                ]
                mod = ofparser.OFPFlowMod(datapath=datapath,
                                          table_id=1,
                                          priority=0,
                                          match=match,
                                          instructions=instructions)
                datapath.send_msg(mod)

        ######################### TABLE 2: ACTIVE PROBING ######################################################

        ################### TABLE 2 CONFIG #########

        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=2,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {IN_PORT} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=2)
        datapath.send_msg(req)
        """ Set update extractor = {IN_PORT}  """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_IN_PORT],
            table_id=2)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=2,
            extractor_id=1,
            field=bebaproto.OXM_EXP_TIMESTAMP)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=2,
            extractor_id=2,
            field=bebaproto.OXM_EXP_PKT_LEN)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            condition=bebaproto.CONDITION_GTE,
            condition_id=0,
            table_id=2,
            operand_1_hf_id=1,
            operand_2_fd_id=4)
        datapath.send_msg(req)

        ############################### TABLE 2 FLOWS #############################

        match = ofparser.OFPMatch(state=0)
        actions = [
            bebaparser.OFPExpActionSetState(table_id=2,
                                            state=1,
                                            idle_timeout=2),
            # saves timestamp
            bebaparser.OFPExpActionSetDataVariable(table_id=2,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=4,
                                                   operand_1_hf_id=1,
                                                   operand_2_cost=PROBE_FREQ),
            ofparser.OFPActionOutput(3)
        ]
        self.add_flow(datapath=datapath,
                      table_id=2,
                      priority=500,
                      match=match,
                      actions=actions)
        """ For every packet coming from spine ports, calculates ewma """
        for i in UPPER_PORTS:
            # simply ewma measuring
            match = ofparser.OFPMatch(state=1, in_port=i, condition0=1)
            actions_ewma_1 = [  # calculates deltaT: FDV[1]=HF[1]-FDV[0]=TS_NOW - TS_LAST
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUB,
                    output_fd_id=1,
                    operand_1_hf_id=1,
                    operand_2_fd_id=0),
                # calculates rate: R = (bytes / deltaT_ms) * 8 [kb/s]
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_MUL,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_cost=8),
                # stores the result in FDV[3]: THE FLOW ESTIMATED RATE
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_DIV,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_fd_id=1),
                # calculates ewma
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_EWMA,
                    output_fd_id=3,
                    operand_1_fd_id=3,
                    operand_2_cost=ALPHA,
                    operand_3_fd_id=2),
                # saves current timestamp
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=0,
                    operand_1_hf_id=1,
                    operand_2_cost=0),
                # saves timestamp + probe freq
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=4,
                    operand_1_hf_id=1,
                    operand_2_cost=PROBE_FREQ),
                # reset byte counter
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUB,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_fd_id=2),
                # saves in GDV[i] the ewma
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUM,
                    output_gd_id=i,
                    operand_1_fd_id=3,
                    operand_2_cost=0)
            ]
            # actions for the packet
            actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)]
            # action group for the probes
            probe_actions1 = [
                ofparser.OFPActionSetField(mpls_tc=datapath.id),  # the GDV[i]
                bebaparser.OFPExpActionWriteContextToField(
                    src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                    src_id=i,
                    dst_field=ofproto.OXM_OF_MPLS_LABEL),
                ofparser.OFPActionOutput(i)
            ]
            probe_actions2 = [
                ofparser.OFPActionSetField(
                    mpls_tc=datapath.id),  # the GDV[other]
                bebaparser.OFPExpActionWriteContextToField(
                    src_type=bebaproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                    src_id=(1 if i == 2 else 2),
                    dst_field=ofproto.OXM_OF_MPLS_LABEL),
                ofparser.OFPActionOutput((1 if i == 2 else 2))
            ]
            # apply packet actions
            insts = [
                ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                               actions),
                # apply packet generation
                bebaparser.OFPInstructionInSwitchPktGen(
                    pkttmp_id=0, actions=probe_actions1),
                bebaparser.OFPInstructionInSwitchPktGen(pkttmp_id=0,
                                                        actions=probe_actions2)
            ]
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      table_id=2,
                                      priority=30,
                                      match=match,
                                      instructions=insts)
            datapath.send_msg(mod)

            match = ofparser.OFPMatch(state=1, in_port=i, condition0=0)
            actions_ewma_2 = [
                bebaparser.OFPExpActionSetDataVariable(
                    table_id=2,
                    opcode=bebaproto.OPCODE_SUM,
                    output_fd_id=2,
                    operand_1_fd_id=2,
                    operand_2_hf_id=2)
            ]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=30,
                          match=match,
                          actions=actions_ewma_2 +
                          [ofparser.OFPActionOutput(3)])

            # using low bitrate flows to refresh the estimates. For testing purposes only
            for j in [0, 1]:
                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x0800,
                                          ip_proto=6,
                                          tcp_dst=10000 + j,
                                          condition0=1)
                actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)]
                self.add_flow(datapath=datapath,
                              table_id=2,
                              priority=150,
                              match=match,
                              actions=actions)

                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x0800,
                                          ip_proto=6,
                                          tcp_src=10000 + j,
                                          condition0=1)
                actions = actions_ewma_1 + [ofparser.OFPActionOutput(3)]
                self.add_flow(datapath=datapath,
                              table_id=2,
                              priority=150,
                              match=match,
                              actions=actions)

                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x0800,
                                          ip_proto=6,
                                          tcp_dst=10000 + j,
                                          condition0=0)
                actions = actions_ewma_2 + [ofparser.OFPActionOutput(3)]
                self.add_flow(datapath=datapath,
                              table_id=2,
                              priority=150,
                              match=match,
                              actions=actions)

                match = ofparser.OFPMatch(in_port=i,
                                          eth_type=0x0800,
                                          ip_proto=6,
                                          tcp_src=10000 + j,
                                          condition0=0)
                actions = actions_ewma_2 + [ofparser.OFPActionOutput(3)]
                self.add_flow(datapath=datapath,
                              table_id=2,
                              priority=150,
                              match=match,
                              actions=actions)

        ######################## TABLE 3: FORWARDING ##############################################################

        ######################## TABLE 3 CONFIG #####################################################################

        ##### GDV[1] contains path utilization to dest 1 on port 1
        ##### GDV[2] contains path utilization to dest 2 on port 1
        ##### GDV[3] contains path utilization to dest 1 on port 2
        ##### GDV[4] contains path utilization to dest 2 on port 2

        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=3,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[
                ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST,
                ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST
            ],
            table_id=3)
        datapath.send_msg(req)
        """ Set update extractor """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[
                ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_DST,
                ofproto.OXM_OF_TCP_SRC, ofproto.OXM_OF_TCP_DST
            ],
            table_id=3)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=0,
            field=ofproto.OXM_OF_MPLS_LABEL)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=1,
            field=bebaproto.OXM_EXP_TIMESTAMP)
        datapath.send_msg(req)

        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=2,
            field=bebaproto.OXM_EXP_PKT_LEN)
        datapath.send_msg(req)

        #################################### TABLE 3 FLOWS ###################################

        # many conditions as the number of LEAVES-1
        # for i in LEAVES except datapath.id: create condition[i]

        # in case of 2 Spines
        for destLeaf in [1, 2]:
            # C[destLeaf]: in which port there is less utilization for that destination?
            req = bebaparser.OFPExpMsgSetCondition(
                datapath=datapath,
                condition=bebaproto.CONDITION_LTE,
                condition_id=destLeaf,
                table_id=3,
                operand_1_gd_id=destLeaf,
                operand_2_gd_id=destLeaf + 2)
            datapath.send_msg(req)

        # leaf number dependent flows
        if datapath.id == 1:
            # LEAF 1 new flows: fetch the destination leaf and check the appropriate condition
            match1true = ofparser.OFPMatch(metadata=2, condition1=1,
                                           state=0)  # dst=2, port 1
            match2true = ofparser.OFPMatch(metadata=3, condition2=1,
                                           state=0)  # dst=3, port 1
            match1false = ofparser.OFPMatch(metadata=2, condition1=0,
                                            state=0)  # dst=2, port 2
            match2false = ofparser.OFPMatch(metadata=3, condition2=0,
                                            state=0)  # dst=3, port 2
        elif datapath.id == 2:
            # LEAF 2 new flows: fetch the destination leaf and check the appropriate condition
            match1true = ofparser.OFPMatch(metadata=1, condition1=1,
                                           state=0)  # dst=1, port 1
            match2true = ofparser.OFPMatch(metadata=3, condition2=1,
                                           state=0)  # dst=3, port 1
            match1false = ofparser.OFPMatch(metadata=1, condition1=0,
                                            state=0)  # dst=1, port 2
            match2false = ofparser.OFPMatch(metadata=3, condition2=0,
                                            state=0)  # dst=3, port 2
        elif datapath.id == 3:
            # LEAF 3 new flows: fetch the destination leaf and check the appropriate condition
            match1true = ofparser.OFPMatch(metadata=1, condition1=1,
                                           state=0)  # dst=1, port 1
            match2true = ofparser.OFPMatch(metadata=2, condition2=1,
                                           state=0)  # dst=2, port 1
            match1false = ofparser.OFPMatch(metadata=1, condition1=0,
                                            state=0)  # dst=1, port 2
            match2false = ofparser.OFPMatch(metadata=2, condition2=0,
                                            state=0)  # dst=2, port 2

        # if port 1 is better, set_state(1) and output 1
        actions_true = [
            bebaparser.OFPExpActionSetState(state=1,
                                            table_id=3,
                                            idle_timeout=RTT),
            ofparser.OFPActionOutput(1)
        ]

        # if port 2 is better, set_state(2) and output 2
        actions_false = [
            bebaparser.OFPExpActionSetState(state=2,
                                            table_id=3,
                                            idle_timeout=RTT),
            ofparser.OFPActionOutput(2)
        ]

        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=20,
                      match=match1true,
                      actions=actions_true)
        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=20,
                      match=match2true,
                      actions=actions_true)
        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=20,
                      match=match1false,
                      actions=actions_false)
        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=20,
                      match=match2false,
                      actions=actions_false)
        """ extract external probes' data and store in GDVs """

        match = ofparser.OFPMatch(eth_type=0x8847, mpls_tc=datapath.id)
        self.add_flow(datapath=datapath,
                      table_id=3,
                      priority=300,
                      match=match,
                      actions=[])

        for i in UPPER_PORTS:
            for leafNo in LEAVES:
                if leafNo != datapath.id:
                    match = ofparser.OFPMatch(in_port=i,
                                              eth_type=0x8847,
                                              mpls_tc=leafNo)
                    """ actions: save in GDVs external probes' data """
                    if datapath.id == 1:
                        if leafNo == 2:
                            actions = [
                                bebaparser.OFPExpActionSetDataVariable(
                                    table_id=3,
                                    opcode=bebaproto.OPCODE_SUM,
                                    output_gd_id=(1 if i == 1 else 3),
                                    operand_1_hf_id=0,
                                    operand_2_cost=0)
                            ]
                        elif leafNo == 3:
                            actions = [
                                bebaparser.OFPExpActionSetDataVariable(
                                    table_id=3,
                                    opcode=bebaproto.OPCODE_SUM,
                                    output_gd_id=(2 if i == 1 else 4),
                                    operand_1_hf_id=0,
                                    operand_2_cost=0)
                            ]
                    elif datapath.id == 2:
                        if leafNo == 1:
                            actions = [
                                bebaparser.OFPExpActionSetDataVariable(
                                    table_id=3,
                                    opcode=bebaproto.OPCODE_SUM,
                                    output_gd_id=(1 if i == 1 else 3),
                                    operand_1_hf_id=0,
                                    operand_2_cost=0)
                            ]
                        elif leafNo == 3:
                            actions = [
                                bebaparser.OFPExpActionSetDataVariable(
                                    table_id=3,
                                    opcode=bebaproto.OPCODE_SUM,
                                    output_gd_id=(2 if i == 1 else 4),
                                    operand_1_hf_id=0,
                                    operand_2_cost=0)
                            ]
                    elif datapath.id == 3:
                        if leafNo == 1:
                            actions = [
                                bebaparser.OFPExpActionSetDataVariable(
                                    table_id=3,
                                    opcode=bebaproto.OPCODE_SUM,
                                    output_gd_id=(1 if i == 1 else 3),
                                    operand_1_hf_id=0,
                                    operand_2_cost=0)
                            ]
                        elif leafNo == 2:
                            actions = [
                                bebaparser.OFPExpActionSetDataVariable(
                                    table_id=3,
                                    opcode=bebaproto.OPCODE_SUM,
                                    output_gd_id=(2 if i == 1 else 4),
                                    operand_1_hf_id=0,
                                    operand_2_cost=0)
                            ]

                    self.add_flow(datapath=datapath,
                                  table_id=3,
                                  priority=200,
                                  match=match,
                                  actions=actions)

        for s in UPPER_PORTS:
            for metadata in LEAVES:
                # normal conditions
                match = ofparser.OFPMatch(in_port=3,
                                          state=s,
                                          metadata=metadata)  # , condition4=0)
                actions = [ofparser.OFPActionOutput(s)]
                self.add_flow(datapath=datapath,
                              table_id=3,
                              priority=30,
                              match=match,
                              actions=actions)
示例#28
0
    def process_packet(self, datapath, act_state, flags, output_ports,
                       ch_state_src, idle_to_src, hard_to_src, ch_state_dst,
                       idle_to_dst, hard_to_dst, priority, count_in):
        """
        Match packet - ethernet, TCP protocol, state (parameter), optional
        flags (parameter).
        """
        if flags == F_DONT_CARE:
            match = ofparser.OFPMatch(eth_type=0x0800,
                                      ip_proto=6,
                                      state=act_state)
        else:
            match = ofparser.OFPMatch(eth_type=0x0800,
                                      ip_proto=6,
                                      state=act_state,
                                      tcp_flags=flags)
        """
        Set actions:
          - Output ports (parameter - list).
          - SetState for both directions (parameters).
        """
        actions = []
        for port in output_ports:
            actions.append(ofparser.OFPActionOutput(port))

        if ch_state_src != self.CH_STATE_NONE:
            actions.append(
                osparser.OFPExpActionSetState(
                    state=ch_state_src,
                    table_id=0,
                    # TODO - TIMEOUTS
                    idle_timeout=idle_to_src,
                    hard_timeout=hard_to_src,
                    bit=0))

        if ch_state_dst != self.CH_STATE_NONE:
            actions.append(
                osparser.OFPExpActionSetState(
                    state=ch_state_dst,
                    table_id=0,
                    # TODO - TIMEOUTS
                    idle_timeout=idle_to_dst,
                    hard_timeout=hard_to_dst,
                    bit=1))
        """
        Set instructions:
          - Apply previously defined actions.
          - Optionally pass packet to table1 for counting.
        """
        inst = [
            ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)
        ]
        if count_in:
            inst.append(ofparser.OFPInstructionGotoTable(table_id=1))
        """
        Prepare and send message.
        """
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=priority,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
示例#29
0
    def load_fsm(self, datapath):
        LOG.info("Loading Table 0 normal FSM ...")
        ##=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
        ## state INIT - ANY
        """
        Match a first packet of a new TCP flow (regardless of TCP flags)
        """
        match = ofparser.OFPMatch(eth_type=0x0800, ip_proto=6, state=self.INIT)
        """
        Forward the packet to the corresponding output interface and create
        entries for both directions of given flow in the OPEN state (forward
        all consecutive packets).

        ( TODO - hard-coded output)
        """
        actions = [
            ofparser.OFPActionOutput(2),
            # Create entry for direction of incoming packet
            osparser.OFPExpActionSetState(
                state=self.OPEN,
                table_id=0,
                # TODO - TIMEOUTS
                idle_timeout=10,
                bit=0),
            # Create entry for opposite direction since response is expected
            osparser.OFPExpActionSetState(
                state=self.OPEN,
                table_id=0,
                # TODO - TIMEOUTS
                idle_timeout=10,
                bit=1)
        ]
        """
        Apply forward actions and the creation of entries, pass the first packet
        to the table1 for the new TCP connections statistics computation.
        """
        inst = [
            ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions),
            ofparser.OFPInstructionGotoTable(table_id=1)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=100,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        ##=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
        ## state OPEN - ANY
        """
        Forward all consecutive packets of already seen flow by matching on
        previously created entries.
        """
        match = ofparser.OFPMatch(eth_type=0x0800, ip_proto=6, state=self.OPEN)
        """
        Just output packet to the corresponding output interface.

        ( TODO - hard-coded output)
        """
        actions = [
            ofparser.OFPActionOutput(2),
            ofparser.OFPActionOutput(1),
            # Refresh timeouts only
            osparser.OFPExpActionSetState(
                state=self.OPEN,
                table_id=0,
                # TODO - TIMEOUTS
                idle_timeout=10,
                bit=0),
            # Refresh timeouts only
            osparser.OFPExpActionSetState(
                state=self.OPEN,
                table_id=0,
                # TODO - TIMEOUTS
                idle_timeout=10,
                bit=1)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=100,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        LOG.info("Done.")
示例#30
0
    def install_edge(self, datapath):
        """ Table 0 is stateless """
        """ Set table 1 as stateful solo per usare GD"""
        req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                       table_id=1,
                                                       stateful=1)
        datapath.send_msg(req)
        """ Set table 3 as stateful """
        req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                       table_id=3,
                                                       stateful=1)
        datapath.send_msg(req)
        """ Set table 4 as stateful """
        req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                       table_id=4,
                                                       stateful=1)
        datapath.send_msg(req)
        """ Set table 5 as stateful """
        req = osparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                       table_id=5,
                                                       stateful=1)
        datapath.send_msg(req)

        ############################### LOOKUP/UPDATE ################
        """ Tab1 """
        """ Non mi interessa """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=1)
        datapath.send_msg(req)
        """ Non mi interessa """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=1)
        datapath.send_msg(req)
        """ Tab3 """
        """ Set lookup extractor = {MPLS_label} """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_MPLS_LABEL],
            table_id=3)
        datapath.send_msg(req)
        """ Set update extractor = {MPLS_label}  """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_MPLS_LABEL],
            table_id=3)
        datapath.send_msg(req)
        """ Tab4 """
        """ Set lookup extractor = {MAC_SRC} """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=4)
        datapath.send_msg(req)
        """ Set update extractor = {MAC_SRC}  """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=4)
        datapath.send_msg(req)
        """ Tab5 """
        """ Set lookup extractor = {MAC_DST} """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_DST],
            table_id=5)
        datapath.send_msg(req)
        """ Set update extractor = {MAC_SRC}  """
        req = osparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=osproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_ETH_SRC],
            table_id=5)
        datapath.send_msg(req)

        ########################### SET HF GD DATA VARIABLE TAB 1 ############################################
        ''' GD[0] = datapath.id<<6 + numero crescente'''
        req = osparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=1,
            global_data_variable_id=0,
            value=(datapath.id << 6) + 1)
        datapath.send_msg(req)

        ########################### SET HF GD DATA VARIABLE TAB 3 ############################################
        ''' HF[0] = OXM_OF_MPLS_LABEL [id_pkt] '''
        req = osparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=0,
            field=ofproto.OXM_OF_MPLS_LABEL)
        datapath.send_msg(req)
        ''' HF[1] = OXM_OF_MPLS_TC [pesoArchi] '''
        req = osparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=3,
            extractor_id=1,
            field=ofproto.OXM_OF_MPLS_TC)
        datapath.send_msg(req)
        ''' GD[0] = 0 '''
        req = osparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=3, global_data_variable_id=0, value=0)
        datapath.send_msg(req)
        ''' GD[1] = datapath.id '''
        req = osparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=3, global_data_variable_id=1, value=0)
        datapath.send_msg(req)

        ########################### SET HF GD DATA VARIABLE TAB 4 ############################################
        ''' HF[0] = OXM_OF_MPLS_LABEL [id_pkt] '''
        req = osparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=4,
            extractor_id=0,
            field=ofproto.OXM_OF_MPLS_LABEL)
        datapath.send_msg(req)
        ''' HF[1] = OXM_OF_MPLS_TC [pesoArchi] '''
        req = osparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=4,
            extractor_id=1,
            field=ofproto.OXM_OF_MPLS_TC)
        datapath.send_msg(req)
        ''' GD[0] = datapath.id '''
        req = osparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath, table_id=4, global_data_variable_id=0, value=1)
        datapath.send_msg(req)

        ########################### SET CONDITION TAB 4 ############################################

        # condition 0: MPLS_TC <= COSTO MEMORIZZATO (FD[0]) ?
        # condition 0: HF[1] <= FD[0] ?
        req = osparser.OFPExpMsgSetCondition(datapath=datapath,
                                             table_id=4,
                                             condition_id=0,
                                             condition=osproto.CONDITION_LTE,
                                             operand_1_hf_id=1,
                                             operand_2_fd_id=0)
        datapath.send_msg(req)

        # condition 1: MPLS_TC <= 1   --> ovvero e il primo hop ?
        # condition 1: HF[1] <= GD[0] ?
        req = osparser.OFPExpMsgSetCondition(datapath=datapath,
                                             table_id=4,
                                             condition_id=1,
                                             condition=osproto.CONDITION_LTE,
                                             operand_1_hf_id=1,
                                             operand_2_gd_id=0)
        datapath.send_msg(req)
        ''' #######################  TAB 0 PushLabelMPLS  '''
        # Se il pacchetto proviene da una porta host (HOST_PORT) push label mpls e GOTO Tab 1
        match = ofparser.OFPMatch(in_port=HOST_PORT)
        actions = [ofparser.OFPActionPushMpls()]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(1)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=8,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        # Se proviene da un'altra porta ha gia la label MPLS GOTO Tab 1 giusto per dirlo esplicitamente perche ci andrebbe da solo CREDO NON DEVO FARE LA PushMpls
        match = ofparser.OFPMatch()
        actions = []  #se proviene da un altra porta ha gia la label MPLS
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(1)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=0,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 1 marca il pkt con ID_PKT  '''
        # Setta la label_mpls se non e gia stata configurata con il valore GD[0] + 1 -> (id_switch << 6) + 1
        match = ofparser.OFPMatch(eth_type=0x8847, mpls_label=0)
        actions = [
            osparser.OFPExpActionWriteContextToField(
                src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_MPLS_LABEL),
            osparser.OFPExpActionSetDataVariable(table_id=1,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_gd_id=0,
                                                 operand_1_gd_id=0,
                                                 operand_2_cost=1)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(2)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=8,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)

        match = ofparser.OFPMatch(eth_type=0x8847)
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(2)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=0,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        ''' #######################  TAB 2 NULLA  serve solo per i bug di OpenFlow, servono 2 stage xke le modifiche MPLS siano visibili'''
        # Non fa niente, ci sta solo per risolvere bug (presunti) di OpenFlow
        match = ofparser.OFPMatch(eth_type=0x8847)
        actions = []
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(3)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=2,
                                  priority=0,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        '''####################### TAB 3 Verifica i duplicati, lo stato e' dato da mpls_label'''
        ''' somma il costo del link di ingresso al valore memorizzato nel pacchetto mpls_tc + 1 '''
        ''' scrive il campo metada = 1 se e' un pacchetto duplicato ovvero nello stato 1 '''
        """ Riga 1 """

        # GD[0] = HF[1] + 1 -> MPLS_TC + 1
        # HF [1] = GD[0] -> MPLS_TC = GD[0]
        # WriteMetadata = 1 -> pacchetto duplicato
        # SetState(1)
        # GOTO Tab 2
        match = ofparser.OFPMatch(state=1, eth_type=0x8847)
        actions = [
            osparser.OFPExpActionSetDataVariable(table_id=3,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_gd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=1),
            osparser.OFPExpActionWriteContextToField(
                src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_MPLS_TC),
            # osparser.OFPExpActionSetState(state=1, table_id=3, idle_timeout=15)]
            osparser.OFPExpActionSetState(state=1, table_id=3)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=1,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(4)
        ]

        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=3,
                                  priority=1198,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        """ Riga 2 """

        # GD[0] = HF[1] + 1 -> MPLS_TC + 1
        # HF [1] = GD[0] -> MPLS_TC = GD[0]
        # SetState(1)
        # GOTO Tab 4
        match = ofparser.OFPMatch(state=0, eth_type=0x8847)
        actions = [
            osparser.OFPExpActionSetDataVariable(table_id=3,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_gd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=1),
            osparser.OFPExpActionWriteContextToField(
                src_type=osproto.SOURCE_TYPE_GLOBAL_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_MPLS_TC),
            # osparser.OFPExpActionSetState(state=1, table_id=3, idle_timeout=15)]
            osparser.OFPExpActionSetState(state=1, table_id=3)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(4)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=3,
                                  priority=198,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        '''# #######################  TAB 4 verifica le condizioni C[0] e C[1]'''
        ''' C[0] verifica se il costo memorizzato nel pacchetto e' <= di quello gia conosciuto (in pratica se il pacchetto ha fatto un percorso migliore) '''
        ''' C[1] serve semplicemente a capire se e' lo switch direttametne collegato all'host che parla e quindi non bisogna fare il pop della label MPLS '''
        ''' le righe BIS verificano la C[1] e non eseguono il POP della label MPLS '''
        ''' metadata = 1 e' un pacchetto duplicato quindi DROP '''
        ''' nel caso imposta metadata = 3 cioe' non e' un pacchetto duplicato ma il costo e' maggiore di quello conosciuto, inoltro senza aggiornare stato '''
        """ Riga 1 """

        # C[0]: MPLS_TC > COSTO MEMORIZZATO -> HF[1] > FD[0]
        # MetaData: 1 -> Pacchetto duplicato
        # azione DROP
        match = ofparser.OFPMatch(state=1,
                                  eth_type=0x8847,
                                  condition0=0,
                                  metadata=1)
        actions = [osparser.OFPExpActionSetState(state=1, table_id=4)]
        self.add_flow(datapath=datapath,
                      table_id=4,
                      priority=1198,
                      match=match,
                      actions=actions)
        """ Riga 2 """

        # C[0]: MPLS_TC > COSTO MEMORIZZATO -> HF[1] > FD[0]
        # MetaData: 0 -> Pacchetto NON duplicato
        # SetState(1)
        # WriteMetadata = 3 -> pacchetto da percorso peggiore ma NON duplicato
        # azione GOTO Tab 3
        match = ofparser.OFPMatch(state=1,
                                  eth_type=0x8847,
                                  condition0=0,
                                  condition1=0,
                                  metadata=0)
        actions = [
            osparser.OFPExpActionSetState(state=1, table_id=4),
            ofparser.OFPActionPopMpls()
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=3,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(5)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=4,
                                  priority=198,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        """ Riga 2 BIS """

        # C[0]: MPLS_TC > COSTO MEMORIZZATO -> HF[1] > FD[0]
        # MetaData: 0 -> Pacchetto NON duplicato
        # SetState(1)
        # WriteMetadata = 3 -> pacchetto da percorso peggiore ma NON duplicato
        # azione GOTO Tab 3
        match = ofparser.OFPMatch(state=1,
                                  eth_type=0x8847,
                                  condition0=0,
                                  condition1=1,
                                  metadata=0)
        actions = [osparser.OFPExpActionSetState(state=1, table_id=4)]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=3,
                                                 metadata_mask=0xFFFFFFFF),
            ofparser.OFPInstructionGotoTable(5)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=4,
                                  priority=198,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        """ Riga 3 """

        # C[0]: MPLS_TC <= COSTO MEMORIZZATO -> HF[1] <= FD[0]
        # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC
        # SetState(1)
        # azione GOTO Tab 3
        match = ofparser.OFPMatch(state=1,
                                  eth_type=0x8847,
                                  condition0=1,
                                  condition1=0)
        actions = [
            osparser.OFPExpActionSetState(state=1, table_id=4),
            osparser.OFPExpActionSetDataVariable(table_id=4,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_fd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=0),
            ofparser.OFPActionPopMpls()
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(5)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=4,
                                  priority=98,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        """ Riga 3 BIS """

        # C[0]: MPLS_TC <= COSTO MEMORIZZATO -> HF[1] <= FD[0]
        # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC
        # SetState(1)
        # azione GOTO Tab 3
        match = ofparser.OFPMatch(state=1,
                                  eth_type=0x8847,
                                  condition0=1,
                                  condition1=1)
        actions = [
            osparser.OFPExpActionSetState(state=1, table_id=4),
            osparser.OFPExpActionSetDataVariable(table_id=4,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_fd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=0)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(5)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=4,
                                  priority=98,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        """ Riga 4 """

        # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC
        # SetState(1)
        # azione GOTO Tab 3
        match = ofparser.OFPMatch(state=0, eth_type=0x8847, condition1=0)
        actions = [
            osparser.OFPExpActionSetState(state=1, table_id=4),
            osparser.OFPExpActionSetDataVariable(table_id=4,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_fd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=0),
            ofparser.OFPActionPopMpls()
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(5)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=4,
                                  priority=8,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        """ Riga 4 BIS """

        # FD[0] = HF[1] -> COSTO MEMORIZZATO = MPLS_TC
        # SetState(1)
        # azione GOTO Tab 3
        match = ofparser.OFPMatch(state=0, eth_type=0x8847, condition1=1)
        actions = [
            osparser.OFPExpActionSetState(state=1, table_id=4),
            osparser.OFPExpActionSetDataVariable(table_id=4,
                                                 opcode=osproto.OPCODE_SUM,
                                                 output_fd_id=0,
                                                 operand_1_hf_id=1,
                                                 operand_2_cost=0)
        ]
        inst = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionGotoTable(5)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=4,
                                  priority=8,
                                  match=match,
                                  instructions=inst)
        datapath.send_msg(mod)
        '''# #######################  TAB 5  semplicemente MAC Learning '''
        ''' Mac Learning ampliato per gestire i metadata = 1 o metadata = 3 '''
        ''' metadata = 1 se e' arrivato fin qui significa che il costo nel pacchetto e' minore di quello conosciuto (ha seguito un percorso migliore) AGGIORNARE e DROP'''
        ''' metadata = 3 non e' un pacchetto duplicato ma il costo del percorso seguito e' peggiore di quello conosciuto NON AGGIORNARE e INOLTRA '''

        # Per ogni input port, per ogni stato
        for i in range(1, N + 1):
            for s in range(N + 1):
                match = ofparser.OFPMatch(in_port=i, state=s)
                if s == 0:
                    out_port = ofproto.OFPP_FLOOD  #serve la flood, dipende se sto su S1 o S6
                else:
                    out_port = s

#				actions = [osparser.OFPExpActionSetState(state=i, table_id=5, hard_timeout=10),
                actions = [
                    osparser.OFPExpActionSetState(state=i, table_id=5),
                    ofparser.OFPActionOutput(out_port)
                ]
                self.add_flow(datapath=datapath,
                              table_id=5,
                              priority=0,
                              match=match,
                              actions=actions)

            # Configuro le entry con azione DROP per i pacchetti duplicati (con metadata = 1)
            match = ofparser.OFPMatch(in_port=i, metadata=1)
            # actions = [osparser.OFPExpActionSetState(state=i, table_id=5, hard_timeout=10)]
            actions = [osparser.OFPExpActionSetState(state=i, table_id=5)]
            self.add_flow(datapath=datapath,
                          table_id=5,
                          priority=1198,
                          match=match,
                          actions=actions)

        # Per ogni stato
        for s in range(N + 1):
            match = ofparser.OFPMatch(state=s, metadata=3)
            if s == 0:
                out_port = ofproto.OFPP_FLOOD  #serve la flood, dipende se sto su S1 o S6
            else:
                out_port = s

            # Configuro le entry per l'output(in_port) senza aggiornare lo stato
            actions = [ofparser.OFPActionOutput(out_port)]
            self.add_flow(datapath=datapath,
                          table_id=5,
                          priority=198,
                          match=match,
                          actions=actions)