Beispiel #1
0
    def setupProtection(self, data=None):
        self.data = data
        Log.info("Setup port protection")
	dt = DevTarget_t(0, hex_to_i16(0xFFFF))

        p = port_down_packet()
        pktlen = self.port_pkt_len = len(p)

        self.tc.conn_mgr.pktgen_write_pkt_buffer(self.tc.hdl, dt, 0, pktlen, str(p))

	offset = 0
        # enable on all pipes

        for pipe in range(0, self.pal.pal_num_pipes_get(0)):
	    port = (pipe << 7 | 68)
            self.tc.conn_mgr.pktgen_enable(self.tc.hdl, 0, (pipe << 7 | 68))
	    Log.debug("Enable pkt gen on port", port)

        config = PktGenAppCfg_t(trigger_type=PktGenTriggerType_t.PORT_DOWN,
                                timer=0,
                                src_port=68,
                                buffer_offset=offset,
                                length=pktlen)
        self.tc.conn_mgr.pktgen_cfg_app(self.tc.hdl, dt, 0, config)
        self.tc.conn_mgr.pktgen_app_enable(self.tc.hdl, dt, 0)
        offset=pktlen
Beispiel #2
0
 def purge(self):
     """
     Delete all current table entries
     """
     [self.delete_table_entry(table_name=e[0], entry=e[1]) for e in self.entries]
     Log.info("Entries purged")
     self.entries = []
Beispiel #3
0
    def message_in(*args, **kwargs):
        """
        Generic message_in handle function
        Triggers corresponding event
        :param kwargs:
        :return:
        """
        packet = kwargs.get('packet')
        switch = kwargs.get('switch')
        try:
            pkt = Ether(packet.packet.payload)
            try:
                Configuration.get('system_done')
            except ConfigurationNotFound:
                return
            if pkt.type == 0xEE00: # its an port down packet
		Log.info("Port:", pkt[PortDown].port_num, "down", "on ingress", pkt[PortDown].pad1, "on pipe")
                Event.trigger("port_down", pkt=pkt)


            if pkt.type == 0xDD00:  # its an topology packet
                Event.trigger("topology_packet_in", packet=pkt, switch=switch)

            if pkt.type == 0x800 and pkt[IP].proto == 2:  # its an igmp packet
                igmp = pkt.payload
                pkt = proto.connection_pb2.GroupPacket(type=int(igmp.type), mc_address=str(igmp.gaddr), src_ip=str(igmp.src), switch=Configuration.get('name'))
                Event.trigger("igmp_packet_to_controller", pkt=pkt)
                Log.debug("Send igmp packet to controller")

        except Exception as e:  # it's not an ethernet frame
            pass
Beispiel #4
0
    def monitor_messages(self):
        """
        Wait for port status message
        """
        Log.info("Start port monitor")
        while True:
            msg = self.sub.recv()
            msg_type = struct.unpack('4s', msg[:4])
            if msg_type[0] == 'PRT|':
                switch_id = struct.unpack('Q', msg[4:12])
                num_statuses = struct.unpack('I', msg[16:20])
                # wir betrachten immer nur den ersten Status
                port, status = struct.unpack('ii', msg[32:40])

                self.port_status[port] = status

                if status == 0:
                    # save port status time
                    # timestamp type, type 2 is port info

                    Log.log_to_file(round((time.time() * 1000) % 1000000), 2, "\r\n", file="logs/port_info.txt")
                    device = TopologyManager.get_device(Configuration.get('name'))
                    device.remove_port(port=port)
                    Event.trigger("topology_change")

                bool_stat = (status == 1)
                Event.trigger("port_msg_to_controller", info=proto.connection_pb2.PortInfo(switch=Configuration.get('name'), port=port, status=bool_stat))
Beispiel #5
0
    def init_flood_group(self):
        """
        This method initializes the multicast group that is responsible for flooding
        """
        p = Popen([self.cli, '--thrift-port',
                   str(self.thrift_port)],
                  stdout=PIPE,
                  stdin=PIPE,
                  stderr=STDOUT)

        # multicast group 1 is flood group
        out, err = p.communicate(input="mc_mgrp_create 1")

        if err:
            Log.error(err)

        p = Popen([self.cli, '--thrift-port',
                   str(self.thrift_port)],
                  stdout=PIPE,
                  stdin=PIPE,
                  stderr=STDOUT)
        out, err = p.communicate(input="mc_node_associate 1 0")
        if err:
            Log.error(err)

        Log.info("Initialize flood group")
def main():

    # without this line, no events would be fired, no topology discovered and no entries computed
    Event.activate()

    # base controller
    controller = BaseController(p4info_file_path=Configuration.get('p4info'),
                                bmv2_path=Configuration.get('bmv2_json'),
                                prog_name=Configuration.get('prog_name'),
                                bin_path=Configuration.get('bin_path'),
                                cxt_json_path=Configuration.get('cxt_path'))

    # register event for new switch connections, this will add switches to device list
    Event.on('new_switch_connection', TopologyManager.add_device)

    # register events for static classes
    Event.on("packet_in",
             MessageInHandler.message_in)  # handles generic packet in
    Event.on("topology_to_controller", GlobalConnection.send_topology_packet
             )  # triggers the send routine to server
    Event.on("igmp_packet_to_controller", GlobalConnection.send_group_packet
             )  # triggers the send routine to server
    Event.on(
        "port_msg_to_controller",
        GlobalConnection.send_port_info)  # triggers the send routine to server

    topology = TopologyController(controller)

    # Create instances of sub controller
    mac = MacController(controller)
    port = PortController(controller=controller)

    pd = PDSetup()
    mc = MulticastController(pd=pd, base=controller)

    # start connection procedure
    init_switches(controller=controller, topology_controller=topology, pd=pd)

    bier = BierController(controller)

    # start grpc server for connection to main controller
    grpc_server = GRPCServer(listen_port=Configuration.get('listen_port'))

    # set controller in local server for table entry
    LocalServer.controller = controller

    # start grpc server
    grpc_server.start()

    # start port monitor
    #threading.Thread(target=port.monitor_messages()).start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        pd.end()
        Log.info("Shutting down")
        os._exit(0)
 def start(self):
     """
     Start grpc server
     This grpc server will be used for the direction global-controller ----> local-controller
     """
     proto.connection_pb2_grpc.add_LocalServerServicer_to_server(LocalServer(), self.server)
     self.server.add_insecure_port('0.0.0.0:' + str(self.listen_port))
     Log.info("Start GRPC Server on port", self.listen_port)
     self.server.start()
    def __init__(self, ip=None, port=0):
        self.channel = grpc.insecure_channel(ip + ":" + str(port))
        self.stub = proto.connection_pb2_grpc.GlobalServerStub(self.channel)

        reponse = self.stub.CheckConnection(proto.connection_pb2.Empty())
        Log.info("Global connection to", ip + ":" + str(port))

        # remove possible old connection when a new global connection is initialized
        Event.on('global_connection', self.close)
Beispiel #9
0
    def set_forwarding_pipeline_config(self):
        """
        Set forwarding pipeline on the switch based on p4info file
        :return:
        """
        try:
            self.__connection.SetForwardingPipelineConfig(p4info=self.__p4info_helper.p4info, prog_name=self.prog_name, bin_path=self.bin_path, cxt_json_path=self.cxt_json_path)
            Event.trigger("switch_arbitrated")
        except Exception as e:
                Log.error("Error in forwarding pipeline", e)

        Log.info("Forwarding pipeline set.")
Beispiel #10
0
    def set_forwarding_pipeline_config(self):
        """
        Set forwarding pipeline on the switch based on p4info file
        :return:
        """
        try:
            self.__connection.SetForwardingPipelineConfig(p4info=self.__p4info_helper.p4info,
                                                          bmv2_json_file_path=self.__bmv2_file_path.encode())
            Event.trigger("switch_arbitrated")
        except Exception as e:
                Log.error("Error in forwarding pipeline", e)

        Log.info("Forwarding pipeline set.")
Beispiel #11
0
    def delete_table_entry(self, table_name=None, entry=None):
        """
        Deletes an table entry on the switch
        :param table_name: table name
        :param entry: table entry
        :return:
        """

        try:
            table_entry = self.__p4info_helper.buildTableEntry(
                table_name=table_name,
                match_fields=entry.match_fields,
                priority=entry.priority)

            self.__connection.DeleteTableEntry(table_entry)

            Log.info("Remove entry:", table_name, entry.match_fields)

            return True
        except Exception as e:
            Log.error("Error in table delete", table_name, entry.match_fields, entry.priority, e)
            return False
Beispiel #12
0
    def connect_and_arbitrate(self, grpc_port=0, device_id=0):
        """
        Connect and arbitrate to the switch
        :param grpc_port: grpc port of the p4 switch
        :param device_id: device id of the p4 switch
        :return:
        """

        i = Configuration.get('bfr_id')
        
        try:
            # add connection to switch
            self.__connection = self.__add_switch_connection(name='s{0}'.format(i),
                                                             address='127.0.0.1:{0}'.format(grpc_port),
                                                             device_id=device_id)

            # start packet in thread
            self.__connection.start_thread()

            if self.__connection.MasterArbitrationUpdate():
                base_mac = int('20:00:00:00:00:00'.translate(None, ":,-"), 16)
                real_mac = format(base_mac + i, 'x')
                mac = ":".join(real_mac[i:i + 2] for i in range(0, len(real_mac), 2))

                Configuration.set('name', 's{0}'.format(i).encode('utf-8'))

                Event.trigger("new_switch_connection", name='s{0}'.format(i),
                              device=Switch(name='s{0}'.format(i).encode('utf-8'), ip='20.0.{0}.0'.format(i).encode('utf-8'),
                                            mac=mac.encode('utf-8'), bfr_id=i))

                Log.info("Arbitration done. Connected to swtich")
                Event.trigger("arbitration_done")
            else:
                Log.error("Master arbitration failed")


        except Exception as e:
            Log.error(e)
Beispiel #13
0
    def add_table_entry(self, table_name=None, entry=None):
        """
        Adds an table entry and locks write request to prevent threading problems
        :param table_name: table name
        :param entry: Table entry
        :return:
        """
        try:
            table_entry = self.__p4info_helper.buildTableEntry(
                table_name=table_name,
                match_fields=entry.match_fields,
                action_name=entry.action_name,
                action_params=entry.action_params,
                priority=entry.priority)

            self.__connection.WriteTableEntry(table_entry)

            Log.info("Add entry:", table_name, entry)

            return True
        except Exception as e:
            Log.error(e, "for", table_name, entry.match_fields, entry.action_name, entry.action_params, entry.priority)
            return False
Beispiel #14
0
 def setMirrorSession(self, config_file=None):
     Log.info("Set mirror session")
     self.mirror.setMirrorSession(Configuration.load(config_file))
Beispiel #15
0
 def close(self):
     Log.info("Global connection removed")
     Event.off('global_connection', self.close)
     self.channel.close()
Beispiel #16
0
 def setPorts(self, config_file=None):
     Log.info("Set ports")
     self.pc.setPorts(Configuration.load(config_file))
Beispiel #17
0
 def end(self):
     Log.info("Close pd connection")
     self.mc.end()
     self.tc.end()
Beispiel #18
0
 def configureTopologyPackets(self, config_file=None):
     Log.info("Configure topology packets")
     self.pm.configureTopologyPackets()
Beispiel #19
0
 def setPortMonitor(self, config_file=None):
     Log.info("Set port monitor")
     self.pm.setupProtection(Configuration.load(config_file))
Beispiel #20
0
 def setFlood(self, config_file=None):
     Log.info("Set flood mc group")
     self.mc.setFlood(Configuration.load(config_file))