示例#1
0
def actions_to_ryu(actions, rule):
    """ Converts a list of actions to a list of ryu actions

        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.

        actions: A iterable list actions such as ActionSet, ActionList,
                 or Bucket.
        rule: The rule being converted
        return: A tuple ([actions], [extra messages])
    """
    ret = []
    extra_messages = []
    for action in actions:
        if action[0] == 'OUTPUT':
            ret.append(parser.OFPActionOutput(action[1]))
        elif action[0] == 'COPY_TTL_OUT':
            ret.append(parser.OFPActionCopyTtlOut())
        elif action[0] == 'COPY_TTL_IN':
            ret.append(parser.OFPActionCopyTtlIn())
        elif action[0] == 'SET_MPLS_TTL':
            ret.append(parser.OFPActionSetMplsTtl(action[1]))
        elif action[0] == 'DEC_MPLS_TTL':
            ret.append(parser.OFPActionDecMplsTtl())
        elif action[0] == 'PUSH_VLAN':
            ret.append(parser.OFPActionPushVlan(action[1]))
        elif action[0] == 'POP_VLAN':
            ret.append(parser.OFPActionPopVlan())
        elif action[0] == 'PUSH_MPLS':
            ret.append(parser.OFPActionPushMpls(action[1]))
        elif action[0] == 'POP_MPLS':
            ret.append(parser.OFPActionPopMpls(action[1]))
        elif action[0] == 'SET_QUEUE':
            ret.append(parser.OFPActionSetQueue(action[1]))
        elif action[0] == 'GROUP':
            if isinstance(action[1], Group):
                group_id, extra = group_to_ryu(action[1], rule)
                ret.append(parser.OFPActionGroup(group_id))
                extra_messages += extra
            else:
                ret.append(parser.OFPActionGroup(action[1]))
        elif action[0] == 'SET_NW_TTL':
            ret.append(parser.OFPActionSetNwTtl(action[1]))
        elif action[0] == 'DEC_NW_TTL':
            ret.append(parser.OFPActionDecNwTtl())
        elif action[0] == 'SET_FIELD':
            set_field = {action[1][0].lower(): action[1][1]}
            ret.append(parser.OFPActionSetField(**set_field))
        elif action[0] == 'PUSH_PBB':
            ret.append(parser.OFPActionPushPbb(action[1]))
        elif action[0] == 'POP_PBB':
            ret.append(parser.OFPActionPopPbb())
        else:
            assert not "GGRR"
    return (ret, extra_messages)
示例#2
0
def pop_mpls(eth_type):
    """Return OpenFlow action list to pop MPLS header and rewrite ethertype.

    Args:
        eth_type (int): ethertype that is set in the packet.
    Returns:
        list: actions to pop MPLS header and rewrite ethertype.
    """

    return [parser.OFPActionPopMpls(eth_type)]
    def _packet_in_handler(self, ev):

        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']
        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        pkt_tcp = pkt.get_protocol(tcp.tcp)
        ip = pkt.get_protocol(ipv4.ipv4)

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        dst = eth.dst
        src = eth.src

        dpid = datapath.id

        self.mac_to_port.setdefault(dpid, {})

        # learn a mac address to avoid FLOOD next time.
        Private_key = 0
        table_id = 1
        #l = [257,260]
        last_item = 4  # we have to assign the correct user ports
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]
        priority = 1
        if ip and dpid in self.Edgeswitch and in_port in range(
                2, last_item + 1):
            if (dpid, src, ip.src, in_port) in self.Hostinfo:
                if src in self.Key.keys():
                    file = open("/home/abdullah/ryu/Key.txt", "r")
                    contents = file.read()
                    dictionary = ast.literal_eval(contents)
                    file.close()
                    self.Key = dictionary
                    if self.Key[src][1] != 0:  # I have to waite the user answer
                        t = self.Key[src]
                        lst = list(t)
                        lst[3] = lst[1]**lst[2] % 21841  #private key
                        t = tuple(lst)
                        self.Key[src] = t
                        Private_key = lst[3]
                    else:
                        return
                print ip.src, "is an authenticated user and its location", dpid, in_port
            else:
                return
            if msg.table_id == 0 and pkt_tcp.bits == 2:
                if Private_key != 0:
                    match = parser.OFPMatch(in_port=in_port,
                                            eth_src=src,
                                            eth_type=0x8847,
                                            mpls_label=Private_key)
                    actions = [
                        parser.OFPActionPopMpls(),
                        parser.OFPActionOutput(out_port)
                    ]
                    inst = [
                        parser.OFPInstructionActions(
                            ofproto.OFPIT_APPLY_ACTIONS, actions)
                    ]
                    mod = parser.OFPFlowMod(datapath=datapath,
                                            table_id=0,
                                            priority=10,
                                            match=match,
                                            instructions=inst)
                    datapath.send_msg(mod)
                    self.Flowcounter[dpid] += 1
                    actions = []
                    match = parser.OFPMatch(in_port=in_port,
                                            eth_type=0x0800,
                                            ip_proto=6,
                                            tcp_flags=2)
                    self.add_flow(datapath, 5, match, actions, table_id=0)
                    return
                else:
                    match = parser.OFPMatch(in_port=in_port,
                                            eth_type=0x0800,
                                            ip_proto=6,
                                            tcp_flags=2)
                    actions = [parser.OFPActionOutput(out_port)]
                    inst = [
                        parser.OFPInstructionActions(
                            ofproto.OFPIT_APPLY_ACTIONS, actions)
                    ]
                    mod = parser.OFPFlowMod(datapath=datapath,
                                            table_id=0,
                                            priority=10,
                                            match=match,
                                            instructions=inst)
                    datapath.send_msg(mod)
                    self.Flowcounter[dpid] += 1
                    print pkt
                    return
        elif dpid in self.Edgeswitch:
            self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
            table_id = 1
        else:
            self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
            table_id = 0

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            if Private_key != 0 and dpid in self.Edgeswitch:
                match = parser.OFPMatch(in_port=in_port, eth_src=src)
                actions = []
                self.add_flow(datapath, 5, match, actions, table_id=1)
                match = parser.OFPMatch(in_port=in_port,
                                        eth_dst=dst,
                                        eth_src=src,
                                        eth_type=0x8847,
                                        mpls_label=Private_key)
                priority = 10
                table_id = 1
                actions = [
                    parser.OFPActionPopMpls(),
                    parser.OFPActionOutput(out_port)
                ]
            else:
                match = parser.OFPMatch(in_port=in_port,
                                        eth_dst=dst,
                                        eth_src=src)
            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & pa enumerate(cket_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath,
                              priority,
                              match,
                              actions,
                              msg.buffer_id,
                              table_id=table_id)
                return
            else:
                self.add_flow(datapath,
                              priority,
                              match,
                              actions,
                              table_id=table_id)
        else:
            pass
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
示例#4
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)
示例#5
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)
示例#6
0
    def install_edge(self, datapath):
        """ Table 0 is stateless """
        """ Set table 1 as stateful for 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 """
        """ Don't care """
        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)
        """ Don't care """
        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 + sequence number'''
        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 [linkWeight] '''
        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 [linkWeight] '''
        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 <= KNOWN WEIGHT (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   --> first 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  '''
        # Input from host port (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)

        match = ofparser.OFPMatch()
        actions = []
        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 mark pkt with ID_PKT  '''
        # Set label_mpls: 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 '''
        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 Check duplicate, State: mpls_label'''
        """ Line 1 """

        # GD[0] = HF[1] + 1 -> MPLS_TC + 1
        # HF [1] = GD[0] -> MPLS_TC = GD[0]
        # WriteMetadata = 1 -> duplicate pkt
        # 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)
        """ Line 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)
        ]
        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 check condition C[0] e C[1]'''
        """ Line 1 """

        # C[0]: MPLS_TC > KNOWN WEIGHT -> HF[1] > FD[0]
        # MetaData: 1 -> duplicate pkt
        # action 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)
        """ Line 2 """

        # C[0]: MPLS_TC > KNOWN WEIGHT -> HF[1] > FD[0]
        # MetaData: 0 -> NOT duplicate
        # SetState(1)
        # WriteMetadata = 3 -> WORSE PATH, NOT duplicate
        # action 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)
        """ Line 2 BIS """

        # C[0]: MPLS_TC > KNOWN WEIGHT -> HF[1] > FD[0]
        # MetaData: 0 -> NOT duplicate
        # SetState(1)
        # WriteMetadata = 3 -> WORSE PATH, NOT duplicate
        # action 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)
        """ Line 3 """

        # C[0]: MPLS_TC <= KNOWN WEIGHT -> HF[1] <= FD[0]
        # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC
        # SetState(1)
        # action 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)
        """ Line 3 BIS """

        # C[0]: MPLS_TC <= KNOWN WEIGHT -> HF[1] <= FD[0]
        # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC
        # SetState(1)
        # action 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)
        """ Line 4 """

        # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC
        # SetState(1)
        # action 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)
        """ Line 4 BIS """

        # FD[0] = HF[1] -> KNOWN WEIGHT = MPLS_TC
        # SetState(1)
        # action 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  simply MAC Learning '''
        ''' Mac Learning, check if metadata = 1 or metadata = 3 '''

        # 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=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)

            # DROP duplicate pkt (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)

        # For each state
        for s in range(N + 1):
            match = ofparser.OFPMatch(state=s, metadata=3)
            if s == 0:
                out_port = ofproto.OFPP_FLOOD
            else:
                out_port = s

            actions = [ofparser.OFPActionOutput(out_port)]
            self.add_flow(datapath=datapath,
                          table_id=5,
                          priority=198,
                          match=match,
                          actions=actions)
    def install_stateful(self, datapath):
        # Send probe packet to packet generation table
        for i in [1, 2, 3, 4]:
            req = bebaparser.OFPExpMsgAddPktTmp(datapath=datapath,
                                                pkttmp_id=i,
                                                pkt_data=pkts[i - 1])
            datapath.send_msg(req)

        # configure stateful stage
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=1,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {ip_dst} """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_L_EXTRACTOR,
            fields=[ofproto.OXM_OF_IPV4_DST],
            table_id=1)
        datapath.send_msg(req)
        """ Set update extractor = {ip_dst} (same as lookup) """
        req = bebaparser.OFPExpMsgKeyExtract(
            datapath=datapath,
            command=bebaproto.OFPSC_EXP_SET_U_EXTRACTOR,
            fields=[ofproto.OXM_OF_IPV4_DST],
            table_id=1)
        datapath.send_msg(req)

        # sampling time
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=1,
            global_data_variable_id=1,
            value=SAMPLING_TIME)
        datapath.send_msg(req)

        # sampling time
        req = bebaparser.OFPExpMsgsSetGlobalDataVariable(
            datapath=datapath,
            table_id=1,
            global_data_variable_id=0,
            value=THRESHOLD)
        datapath.send_msg(req)

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

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

        # threshold exceeding condition
        req = bebaparser.OFPExpMsgSetCondition(
            datapath=datapath,
            condition=bebaproto.CONDITION_GTE,
            condition_id=2,
            table_id=1,
            operand_1_fd_id=2,
            operand_2_gd_id=0)
        datapath.send_msg(req)

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

        # metadata extractor
        req = bebaparser.OFPExpMsgHeaderFieldExtract(
            datapath=datapath,
            table_id=1,
            extractor_id=0,
            field=ofproto.OXM_OF_METADATA)
        datapath.send_msg(req)

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

        ############################# TAB 0: STATELESS ####################################
        # configure stateful stage
        req = bebaparser.OFPExpMsgConfigureStatefulTable(datapath=datapath,
                                                         table_id=0,
                                                         stateful=1)
        datapath.send_msg(req)
        """ Set lookup extractor = {ip_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 = {ip_dst} (same as lookup) """
        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)
        """ #T0_R1 """
        # Parse MPLS info: send state in metadata in the right position
        # it is needed to match the right ip extractor in tab 1
        match = ofparser.OFPMatch(eth_type=0x8847)
        actions = [
            bebaparser.OFPExpActionSetDataVariable(table_id=0,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=0,
                                                   operand_1_hf_id=0,
                                                   operand_2_cost=0),
            bebaparser.OFPExpActionWriteContextToField(
                src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                src_id=0,
                dst_field=ofproto.OXM_OF_METADATA),
            ofparser.OFPActionPopMpls()
        ]
        instructions = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=0x88470000,
                                                 metadata_mask=0xffff0000),
            ofparser.OFPInstructionGotoTable(1)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=100,
                                  match=match,
                                  instructions=instructions)
        datapath.send_msg(mod)
        """ #T0_R2 """
        # if pkt has dscp=13 it's passing through the second stateful switch,
        #   so this packet has not to be counted: directly to forwarding
        match = ofparser.OFPMatch(eth_type=0x800)
        instructions = [ofparser.OFPInstructionGotoTable(2)]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=0,
                                  match=match,
                                  instructions=instructions)
        datapath.send_msg(mod)
        """ #T0_R3 """
        # All other packets go to tab 1 for counting
        match = ofparser.OFPMatch(eth_type=0x800, ip_dscp=0)
        instructions = [ofparser.OFPInstructionGotoTable(1)]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=0,
                                  priority=50,
                                  match=match,
                                  instructions=instructions)
        datapath.send_msg(mod)
        """ #T0_R4 """
        # For now packets coming from host ports are dropped
        match = ofparser.OFPMatch(in_port=HOST_PORT)
        actions = []
        self.add_flow(datapath=datapath,
                      table_id=0,
                      priority=500,
                      match=match,
                      actions=actions)

        ############################### TAB 1: STATEFUL ############################################
        """ For each state entry
            FDV[0]: count
            FDV[1]: delta timestamp
            FDV[2]: ewma representing switch's own state
            FDV[3]: global state
        """

        # common instructions
        instGoto2 = [ofparser.OFPInstructionGotoTable(2)]

        # this entry saves the state contained in the mpls pkt
        match = ofparser.OFPMatch(metadata=(0x88470000, 0xffff0000),
                                  eth_type=0x800)
        actions = [
            bebaparser.OFPExpActionSetDataVariable(table_id=1,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=3,
                                                   operand_1_hf_id=0,
                                                   operand_2_fd_id=2)
        ]
        insts = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions)
        ]
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=200,
                                  match=match,
                                  instructions=insts)
        datapath.send_msg(mod)

        # packet counter ++
        actionUpdateCounter = [
            bebaparser.OFPExpActionSetDataVariable(table_id=1,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=0,
                                                   operand_1_fd_id=0,
                                                   operand_2_cost=1)
        ]
        # reset counter to 0
        actionResetCounter = [
            bebaparser.OFPExpActionSetDataVariable(table_id=1,
                                                   opcode=bebaproto.OPCODE_SUB,
                                                   output_fd_id=0,
                                                   operand_1_fd_id=0,
                                                   operand_2_fd_id=0)
        ]
        # save timestamp+sampling_time
        actionSaveTimestamp = [
            bebaparser.OFPExpActionSetDataVariable(table_id=1,
                                                   opcode=bebaproto.OPCODE_SUM,
                                                   output_fd_id=1,
                                                   operand_1_hf_id=1,
                                                   operand_2_gd_id=1)
        ]

        # Calculates EWMA on packet number
        actionEvaluateEWMA = [
            bebaparser.OFPExpActionSetDataVariable(
                table_id=1,
                opcode=bebaproto.OPCODE_MUL,
                output_fd_id=0,
                operand_1_fd_id=0,
                operand_2_cost=MULTIPLY_FACTOR),
            bebaparser.OFPExpActionSetDataVariable(
                table_id=1,
                opcode=bebaproto.OPCODE_EWMA,
                output_fd_id=2,
                operand_1_fd_id=2,
                operand_2_cost=bebaproto.EWMA_PARAM_0875,
                operand_3_fd_id=0)
        ]

        actionSetDSCPAttack = [ofparser.OFPActionSetField(ip_dscp=26)]
        actionSetDSCPNormal = [ofparser.OFPActionSetField(ip_dscp=13)]
        """ Measures and state transitions """
        """ #T1_R1 """
        """ First packet of a flow """
        match = ofparser.OFPMatch(state=0, eth_type=0x800)
        actions = [bebaparser.OFPExpActionSetState(state=1, table_id=1, idle_timeout=MONITORING_TIMEOUT)] + \
                  actionUpdateCounter + actionSaveTimestamp + actionSetDSCPNormal
        insts = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions)
        ] + instGoto2
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=50,
                                  match=match,
                                  instructions=insts)
        datapath.send_msg(mod)
        """ #T1_R2 """
        """ State is MONITORING; in between the window
            ACTIONS: counter++ and set NORMAL DSCP info"""
        match = ofparser.OFPMatch(state=1, condition0=0, eth_type=0x800)
        actions = actionUpdateCounter + actionSetDSCPNormal
        insts = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions)
        ] + instGoto2
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=15,
                                  match=match,
                                  instructions=insts)
        datapath.send_msg(mod)
        """ #T1_R3 """
        """ State is MONITORING; sampling time expired
            ACTIONS: evaluate EWMA, counter = 0, save new timestamp+SAMPLING, push mpls, write ewma value to label"""

        for i in [1, 2, 3, 4]:
            match = ofparser.OFPMatch(ipv4_dst='10.0.0.' + str(i),
                                      state=1,
                                      condition0=1,
                                      eth_type=0x800)
            actions = actionEvaluateEWMA + actionResetCounter + actionSaveTimestamp
            insp_actions = [
                bebaparser.OFPExpActionWriteContextToField(
                    src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                    src_id=2,
                    dst_field=ofproto.OXM_OF_MPLS_LABEL),
                ofparser.OFPActionSetField(mpls_tc=datapath.id),
                ofparser.OFPActionOutput(2)
            ]
            insts = [
                ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                               actions),
                bebaparser.OFPInstructionInSwitchPktGen(pkttmp_id=i,
                                                        actions=insp_actions)
            ] + instGoto2
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      table_id=1,
                                      priority=20,
                                      match=match,
                                      instructions=insts)
            datapath.send_msg(mod)
        """ #T1_R4 """
        """ State is in MONITORING, the switch's own state is over threshold now
            ACTIONS: go to ATTACK state and trigger the control message """
        match = ofparser.OFPMatch(state=1, condition2=1, eth_type=0x800)
        # apply mitigation policy
        actions = [bebaparser.OFPExpActionSetState(state=2, table_id=1)] +\
                  actionSetDSCPAttack
        insts = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions)
        ] + instGoto2
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=30,
                                  match=match,
                                  instructions=insts)
        datapath.send_msg(mod)
        """ #T1_R5 """
        """ State is MONITORING, The sum of the 2 states is over threshold now """
        match = ofparser.OFPMatch(state=1, condition1=1, eth_type=0x800)
        actions = [bebaparser.OFPExpActionSetState(state=2, table_id=1)
                   ] + actionSetDSCPAttack
        insts = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions)
        ] + instGoto2
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=30,
                                  match=match,
                                  instructions=insts)
        datapath.send_msg(mod)
        """ #T1_R6 """
        """ State is ATTACK, no more over threshold, either the sum of states or switch's own state"""
        match = ofparser.OFPMatch(state=2,
                                  condition1=0,
                                  condition2=0,
                                  eth_type=0x800)
        actions = [bebaparser.OFPExpActionSetState(state=1, table_id=1, idle_timeout=MONITORING_TIMEOUT)] +\
                  actionSetDSCPNormal
        insts = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            # RETURNED UNDER THRESHOLD
            ofparser.OFPInstructionWriteMetadata(metadata=11,
                                                 metadata_mask=0xffffffff)
        ] + instGoto2
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=100,
                                  match=match,
                                  instructions=insts)
        datapath.send_msg(mod)
        """ #T1_R7 """
        """ State is ATTACK, monitor condition is valid"""
        match = ofparser.OFPMatch(state=2, condition0=0, eth_type=0x800)
        actions = actionUpdateCounter + actionSetDSCPAttack
        insts = [
            ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                           actions),
            ofparser.OFPInstructionWriteMetadata(metadata=22,
                                                 metadata_mask=0xffffffff)
        ] + instGoto2
        mod = ofparser.OFPFlowMod(datapath=datapath,
                                  table_id=1,
                                  priority=50,
                                  match=match,
                                  instructions=insts)
        datapath.send_msg(mod)
        """ #T1_R8 """
        """ State is ATTACK, trigger control message """
        for i in [1, 2, 3, 4]:
            match = ofparser.OFPMatch(ipv4_dst='10.0.0.' + str(i),
                                      state=2,
                                      condition0=1,
                                      eth_type=0x800)
            actions = actionEvaluateEWMA + actionResetCounter + actionSaveTimestamp + actionSetDSCPAttack
            insp_actions = [
                bebaparser.OFPExpActionWriteContextToField(
                    src_type=bebaproto.SOURCE_TYPE_FLOW_DATA_VAR,
                    src_id=2,
                    dst_field=ofproto.OXM_OF_MPLS_LABEL),
                ofparser.OFPActionSetField(mpls_tc=datapath.id),
                ofparser.OFPActionOutput(2)
            ]
            insts = [
                ofparser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                               actions),
                bebaparser.OFPInstructionInSwitchPktGen(pkttmp_id=i,
                                                        actions=insp_actions)
            ] + instGoto2
            mod = ofparser.OFPFlowMod(datapath=datapath,
                                      table_id=1,
                                      priority=50,
                                      match=match,
                                      instructions=insts)
            datapath.send_msg(mod)

        ########################    TAB 2: STATELESS    ########################################
        """ #T2_R1 """
        # Pkts destined to host attached to switch
        match = ofparser.OFPMatch(eth_type=0x800,
                                  ipv4_dst=server_dict[datapath.id])
        actions = [ofparser.OFPActionOutput(HOST_PORT)]
        self.add_flow(datapath=datapath,
                      table_id=2,
                      priority=70,
                      match=match,
                      actions=actions)

        # SW 2
        """ #T2_R2-3 """
        if datapath.id == 2:
            """ Stateful switches IN_PORT output actions """
            match = ofparser.OFPMatch(in_port=1,
                                      eth_type=0x800,
                                      ipv4_dst=addrs[3])
            actions = [ofparser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=50,
                          match=match,
                          actions=actions)

            match = ofparser.OFPMatch(in_port=2,
                                      eth_type=0x800,
                                      ipv4_dst=addrs[2])
            actions = [ofparser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=50,
                          match=match,
                          actions=actions)

        # SW 6
        elif datapath.id == 6:
            """ #T2_R4-5 """
            """ Stateful switches IN_PORT output actions """
            match = ofparser.OFPMatch(in_port=1,
                                      eth_type=0x800,
                                      ipv4_dst=addrs[2])
            actions = [ofparser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=50,
                          match=match,
                          actions=actions)

            match = ofparser.OFPMatch(in_port=2,
                                      eth_type=0x800,
                                      ipv4_dst=addrs[3])
            actions = [ofparser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=50,
                          match=match,
                          actions=actions)

        # All other packets -> out
        """ #T2_R6-7 """
        for p in CORE_PORTS:
            match = ofparser.OFPMatch(in_port=p, eth_type=0x800)
            actions = [ofparser.OFPActionOutput(1 if p == 2 else 2)]
            self.add_flow(datapath=datapath,
                          table_id=2,
                          priority=0,
                          match=match,
                          actions=actions)
示例#8
0
 def switch_features_handler(self, ev):
     datapath = ev.msg.datapath
     # ofp = datapath.ofproto
     # ofp_parser = datapath.ofproto_parser
     from ryu.ofproto import ofproto_v1_3 as ofp
     from ryu.ofproto import ofproto_v1_3_parser as ofp_parser
     mod = [
         ofp_parser.OFPFlowMod(
             datapath=datapath,
             table_id=0,
             priority=0,
             instructions=[ofp_parser.OFPInstructionGotoTable(table_id=1)]),
         ofp_parser.OFPFlowMod(
             datapath=datapath,
             table_id=0,
             priority=1,
             match=ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_ARP),
             instructions=[ofp_parser.OFPInstructionGotoTable(table_id=3)]),
         ofp_parser.OFPFlowMod(
             datapath=datapath,
             table_id=1,
             priority=0,
             instructions=[ofp_parser.OFPInstructionGotoTable(table_id=2)]),
         ofp_parser.OFPFlowMod(
             datapath=datapath,
             table_id=1,
             priority=1,
             match=ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP),
             instructions=[
                 ofp_parser.OFPInstructionActions(
                     type_=ofp.OFPIT_APPLY_ACTIONS,
                     actions=[
                         ofp_parser.OFPActionPushMpls(),
                         # ofp_parser.OFPActionSetField(mpls_label=0x1234),
                         ofp_parser.OFPActionPushMpls(),
                         # ofp_parser.OFPActionSetField(mpls_label=0x1235)
                     ]),
                 ofp_parser.OFPInstructionGotoTable(table_id=3)
             ]),
         ofp_parser.OFPFlowMod(
             datapath=datapath,
             table_id=1,
             priority=2,
             match=ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_MPLS,
                                       mpls_bos=0),
             instructions=[
                 ofp_parser.OFPInstructionActions(
                     type_=ofp.OFPIT_APPLY_ACTIONS,
                     actions=[
                         ofp_parser.OFPActionPopMpls(
                             ether_types.ETH_TYPE_MPLS)
                     ]),
                 ofp_parser.OFPInstructionGotoTable(table_id=2),
             ]),
         ofp_parser.OFPFlowMod(
             datapath=datapath,
             table_id=2,
             priority=0,
             instructions=[ofp_parser.OFPInstructionGotoTable(table_id=3)]),
         ofp_parser.OFPFlowMod(
             datapath=datapath,
             table_id=2,
             priority=1,
             match=ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_MPLS,
                                       mpls_bos=1),
             instructions=[
                 ofp_parser.OFPInstructionActions(
                     type_=ofp.OFPIT_APPLY_ACTIONS,
                     actions=[
                         ofp_parser.OFPActionPopMpls(
                             ether_types.ETH_TYPE_IP)
                     ]),
                 ofp_parser.OFPInstructionGotoTable(table_id=3)
             ]),
         ofp_parser.OFPFlowMod(
             datapath=datapath,
             table_id=3,
             priority=0,
             instructions=[
                 ofp_parser.OFPInstructionActions(
                     type_=ofp.OFPIT_APPLY_ACTIONS,
                     actions=[
                         ofp_parser.OFPActionOutput(
                             port=ofp.OFPP_CONTROLLER),
                         ofp_parser.OFPActionOutput(port=ofp.OFPP_FLOOD)
                     ])
             ])
     ]
     for msg in mod:
         datapath.send_msg(msg)