def do_flow_mod(self, event=None):
        """
        If the event is not specified, then issues a flow mod with random src
        and dst ports; all the other fields will match against the trigger event
        saved earlier. Does not issue pkt_out.
        
        Otherwise, does a normal flow_mod.
        
        """
        msg = of.ofp_flow_mod()

        # Normal flow-mod
        if event:
            msg.match = of.ofp_match.from_packet(event.parse())
            msg.actions.append(of.ofp_action_output(port=get_the_other_port(event.port)))
            msg.buffer_id = event.ofp.buffer_id
            
            # Save the trigger event for later matching.
            if msg.match.tp_dst == TRIGGER_PORT:
                with self.lock:
                    self.trigger_event = event
                mylog('Received trigger event. Trigger event.parse() =', pretty_dict(dictify(event.parse())))
            
            mylog('Installed flow:', pretty_dict(dictify(msg.match)))
            
        # Special flow-mod that generates random source/dst ports.
        else:
            with self.lock:
                assert self.trigger_event
                trigger_packet = func_cache(self.trigger_event.parse)
                msg.match = of.ofp_match.from_packet(trigger_packet)
                msg.actions.append(of.ofp_action_output(port=get_the_other_port(self.trigger_event.port)))
            msg.match.tp_dst = random.randint(10, 65000)
            msg.match.tp_src = random.randint(10, 65000)
            
        current_time = time.time()
        with self.lock:
            (count, start, _) = self.flow_mod_stat
            if start is None: start = current_time
            self.flow_mod_stat = (count + 1, start, current_time)

        msg.idle_timeout = IDLE_TIMEOUT
        msg.hard_timeout = HARD_TIMEOUT

        if (not USE_LIMITER) or (USE_LIMITER and self.flow_mod_limiter.to_forward_packet()):
            self._of_send(msg)
        
        self.flow_mod_queue.put((current_time, event.parse()))
Exemple #2
0
    def _install_rule(self, event, packet, outport, tp_dst=None, idle_timeout=IDLE_TIMEOUT):
        """
        Installs a rule for any incoming packet, doing what a learning switch
        should do.
        
        """
        msg = of.ofp_flow_mod()
        msg.match = of.ofp_match.from_packet(packet)
        msg.idle_timeout = idle_timeout
        msg.hard_timeout = HARD_TIMEOUT
        msg.actions.append(of.ofp_action_output(port=outport))

        with exp_control.lock:
            exp_control.flow_mod_count += 1
            install_bogus_rules = exp_control.install_bogus_rules

        # Install a rule with a randomly generated dest mac address that no
        # one will ever match against.
        if install_bogus_rules:
            # mac_addr_list = ['0' + str(random.randint(1,9)) for _ in range(6)]
            # msg.match.dl_src = EthAddr(':'.join(mac_addr_list))
            msg.match.tp_dst = random.randint(10, 65000)
            msg.match.tp_src = random.randint(10, 65000)
            msg.buffer_id = event.ofp.buffer_id
            mylog("Installing a bogus flow.")

        # Create a rule that matches with the incoming packet. When buffer ID is
        # specified, the flow mod command is automatically followed by a packet-
        # out command.
        elif tp_dst is None:
            msg.buffer_id = event.ofp.buffer_id
            with exp_control.lock:
                exp_control.pkt_out_count += 1
            mylog("installing flow for %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, outport))

        # Create a rule with a specific dest port.
        else:
            msg.match.tp_dst = tp_dst
            mylog("Installing rule for tp_dst =", tp_dst)

        current_time = time.time()
        with exp_control.lock:
            if exp_control.flow_mod_start_time is None:
                exp_control.flow_mod_start_time = current_time
            exp_control.flow_mod_end_time = current_time

        mylog("Flow_mod:", pretty_dict(dictify(msg)))
        self.connection.send(msg)
Exemple #3
0
    def _handle_command(self, sock):
        
        try:
            cmd_list = sock.recv()
        except ConnectionClosed:
            return False
        
        if cmd_list[0] == 'GET':
            # ['GET', 'name_of_attr'] -> value_obj
            with self._lock:
                ret = getattr(self._local_obj, cmd_list[1])
            sock.send(ret)

        elif cmd_list[0] == 'GETALL':
            # ['GETALL'] -> obj's dict
            with self._lock:
                ret = pretty_dict(self._local_obj.__dict__)
            sock.send(ret)
        
        elif cmd_list[0] == 'SET':
            # ['SET', 'name_of_attr', value_obj] -> 'OK'
            with self._lock:
                setattr(self._local_obj, cmd_list[1], cmd_list[2])
            sock.send('OK')
            
        elif cmd_list[0] == 'RESET':
            # ['RESET'] -> 'OK'
            self._reset_func()
            sock.send('OK')
            
        elif cmd_list[0] == 'RUN':
            # ['RUN', 'func_name', 'param1', 'param2', ...] -> ret obj
            func = getattr(self._local_obj, cmd_list[1])
            ret = func(*cmd_list[2:])
            sock.send(ret)
            
        elif cmd_list[0] == 'EXIT':
            os._exit(0)
            
        elif cmd_list[0] == 'HELLO':
            sock.send('Hi there!')
            
        else:
            raise RuntimeError('Bad command: %s' % cmd_list)
        
        return True