Exemple #1
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))
    def handle_topology_answer(self, pkt=None):
        """
        Handle topology packet
        :param pkt: contains the topology packet
        :return:
        """

        # if the controller is not yet connected to all local controllers
        # don't handle topology packets
        if not Configuration.get('system_done'):
            return

        ip = pkt.ip.encode('utf-8')
        mac = pkt.mac.encode('utf-8')
        name = pkt.name.encode('utf-8')
        port = pkt.port
        switch = pkt.switch.encode('utf-8')

        if name.startswith('h'):  # it's a host
            TopologyManager.add_device(name=name,
                                       device=Host(name=name, ip=ip, mac=mac))
            TopologyManager.get_device(name=name).add_device_to_port(
                device=switch, port=1)

        Log.event("topology packet with identifier", name, "from switch",
                  switch, "on port", port, "with ip", ip)

        if TopologyManager.get_device(name=switch).add_device_to_port(
                device=name, port=int(port)):
            Event.trigger("topology_change",
                          src_device=switch,
                          dst_device=name,
                          port=int(port))
Exemple #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 == 0xDD00:  # its an topology packet
                Event.trigger("topology_packet_in", packet=pkt, switch=switch)

            if pkt.type == 0x800:  # its an igmp packet
                igmp = pkt.payload.payload
                pkt = proto.connection_pb2.GroupPacket(
                    type=int(igmp.type),
                    mc_address=str(igmp.gaddr),
                    src_ip=str(pkt.payload.src),
                    switch=Configuration.get('name'))
                Event.trigger("igmp_packet_to_controller", pkt=pkt)

        except Exception as e:  # it's not an ethernet frame
            pass
Exemple #4
0
    def stream_recv(self, stream):
        try:
            for p in stream:
                self.stream_in_q.put(p)
                Event.trigger("packet_in", packet=p, switch=self.name)

        except grpc.RpcError as e:
            pass  # arbitration end
    def Hello(self, request, context):
        Event.trigger('global_connection')
        GlobalConnection.global_connection = GlobalConnection(ip=request.ip, port=request.port)

        device = TopologyManager.get_device(Configuration.get('name'))

        return proto.connection_pb2.SwitchInfo(name=Configuration.get('name'),
                                               ip=device.get_ip(),
                                               mac=device.get_mac(),
                                               bfr_id=device.get_bfr_id(0))
    def updatePorts(self, pkt=None):
        port = pkt[PortDown].port_num
        device = TopologyManager.get_device(Configuration.get('name'))
        device.remove_port(port=port)
        Event.trigger("topology_change")

        Event.trigger("port_msg_to_controller",
                      info=proto.connection_pb2.PortInfo(
                          switch=Configuration.get('name'),
                          port=port,
                          status=False))
Exemple #7
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.")
Exemple #8
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.")
Exemple #9
0
    def PortMessage(self, request, context):
        """
        This method receives a port message
        """
        Log.async_info("Got port message")
        Log.async_debug(request)

        # this event is not catched yet
        # for demonstration purpose, the topology doesn't get updated
        # on a link failure
        Event.trigger("port_message", message=request)

        return proto.connection_pb2.Status(code=1, message="Accepted")
Exemple #10
0
    def handle_packet_in(pkt):
        switch = pkt.switch.encode('utf-8')
        mc_addr = pkt.mc_address.encode('utf-8')
        src_ip = pkt.src_ip.encode('utf-8')

        if pkt.type == 0x16:
            GroupManager.add_to_group(switch, src_ip, mc_addr)
        elif pkt.type == 0x17:
            GroupManager.remove_from_group(switch, src_ip, mc_addr)

        Event.trigger("group_update")

        Log.event("Got igmp packet with type", hex(pkt.type), "and src",
                  src_ip, "for group", mc_addr, "from", switch)
Exemple #11
0
    def show_all():
        """
        Show current configuration
        :return:
        """
        data = PrettyTable()

        data.field_names = ["Name", "Value"]

        for key, value in Configuration.settings.iteritems():
            if key == "switches":
                value = "Switch-Array - Omitted due to length"
            data.add_row([key, value])

        Event.trigger('log_to_input', str=(str(data)))
    def __init__(self, grpc_address=None):
        self.channel = grpc.insecure_channel(grpc_address)
        self.stub = proto.connection_pb2_grpc.LocalServerStub(self.channel)

        response = self.stub.Hello(
            proto.connection_pb2.HelloMessage(
                ip="127.0.0.1", port=int(Configuration.get('listen_port'))))
        self.name = response.name.encode('utf-8')

        Event.trigger('new_switch_connection',
                      name=self.name,
                      device=Switch(name=self.name,
                                    ip=response.ip.encode('utf-8'),
                                    mac=response.mac.encode('utf-8'),
                                    bfr_id=response.bfr_id))
Exemple #13
0
    def connect(self):
        """
        All switches grpc addresses are in ascending order.
        Connect until a connection can't be established
        :return:
        """

        for switch in Configuration.get("switches"):
            try:
                self.__connections[switch["name"]] = SwitchConnection(
                    grpc_address='127.0.0.1:{0}'.format(
                        switch["local_controller_port"]))
                Log.async_debug("Connected to controller on port",
                                switch["local_controller_port"])
                Event.trigger('switch_connected', name=switch["name"])
            except grpc.RpcError as e:
                raise SwitchConnectionFailed(switch["name"],
                                             switch["local_controller_port"])

        Log.async_info("Connected to", len(self.__connections), "controller")
        Configuration.set('connected', True)
    def handle_topology_answer(self, *args, **kwargs):
        """
        Handle topology packet
        :param args: contains the topology packet
        :return:
        """
        packet = kwargs.get('packet')
        switch = kwargs.get('switch')

        pkt = packet

        pkt = packet.payload

        Event.trigger("clear_port_down", port=int(pkt.port))

        if pkt.device_type != 1:
            name = "s" + str(pkt.identifier)
            TopologyManager.add_device(name=name, device=Host(name=name, ip=pkt.ip, mac=pkt.mac))
        else:  # its a host
            name = "h" + str(pkt.identifier)
            TopologyManager.add_device(name=name, device=Host(name=name, ip=pkt.ip, mac=pkt.mac))

        if TopologyManager.get_device(name=switch).add_device_to_port(device=name, port=int(pkt.port)):
            Event.trigger("topology_change", src_device=switch, dst_device=name, port=int(pkt.port))

	#Log.info("Pkt in:", pkt.port)
        topology_packet = proto.connection_pb2.TopologyPacket(ip=pkt.ip, mac=pkt.mac, port=pkt.port, name=name, switch=Configuration.get('name'))

        Event.trigger("topology_to_controller", pkt=topology_packet)
Exemple #15
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
Exemple #16
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)
Exemple #17
0
    def TopologyMessage(self, request, context):
        Event.trigger("topology_packet_in", pkt=request)

        return proto.connection_pb2.Status(code=1, message="accepted")
Exemple #18
0
 def echo(msg):
     Event.trigger('log_to_input', str=(str(msg)))
Exemple #19
0
 def async_debug(*args):
     if Configuration.get("debug"):
         Event.trigger('log_to_output', str=('[D]' + ' ' + ' '.join(map(str, args))))
Exemple #20
0
 def async_info(*args):
     Event.trigger('log_to_output', str=('[I]' + ' ' + ' '.join(map(str, args))))
Exemple #21
0
 def _(event):
     " Pressing Ctrl-Q or Ctrl-C will exit the user interface. "
     Event.trigger('exit')
     event.app.exit()